001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.layoutsadmin.lar;
016    
017    import com.liferay.counter.service.CounterLocalServiceUtil;
018    import com.liferay.portal.NoSuchLayoutException;
019    import com.liferay.portal.kernel.dao.orm.QueryUtil;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.json.JSONFactoryUtil;
022    import com.liferay.portal.kernel.json.JSONObject;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.spring.osgi.OSGiBeanProperties;
026    import com.liferay.portal.kernel.util.ArrayUtil;
027    import com.liferay.portal.kernel.util.CharPool;
028    import com.liferay.portal.kernel.util.Constants;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.ListUtil;
031    import com.liferay.portal.kernel.util.LocaleUtil;
032    import com.liferay.portal.kernel.util.MapUtil;
033    import com.liferay.portal.kernel.util.StringBundler;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.StringUtil;
036    import com.liferay.portal.kernel.util.UnicodeProperties;
037    import com.liferay.portal.kernel.util.Validator;
038    import com.liferay.portal.kernel.xml.Element;
039    import com.liferay.portal.model.Group;
040    import com.liferay.portal.model.Image;
041    import com.liferay.portal.model.Layout;
042    import com.liferay.portal.model.LayoutBranch;
043    import com.liferay.portal.model.LayoutConstants;
044    import com.liferay.portal.model.LayoutFriendlyURL;
045    import com.liferay.portal.model.LayoutPrototype;
046    import com.liferay.portal.model.LayoutRevision;
047    import com.liferay.portal.model.LayoutSet;
048    import com.liferay.portal.model.LayoutStagingHandler;
049    import com.liferay.portal.model.LayoutTemplate;
050    import com.liferay.portal.model.LayoutTypePortlet;
051    import com.liferay.portal.model.LayoutTypePortletConstants;
052    import com.liferay.portal.model.adapter.StagedTheme;
053    import com.liferay.portal.model.adapter.impl.StagedThemeImpl;
054    import com.liferay.portal.service.GroupLocalServiceUtil;
055    import com.liferay.portal.service.ImageLocalServiceUtil;
056    import com.liferay.portal.service.LayoutFriendlyURLLocalServiceUtil;
057    import com.liferay.portal.service.LayoutLocalServiceUtil;
058    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
059    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
060    import com.liferay.portal.service.LayoutTemplateLocalServiceUtil;
061    import com.liferay.portal.service.PortletLocalServiceUtil;
062    import com.liferay.portal.service.ResourceLocalServiceUtil;
063    import com.liferay.portal.service.ServiceContext;
064    import com.liferay.portal.service.ServiceContextThreadLocal;
065    import com.liferay.portal.service.impl.LayoutLocalServiceHelper;
066    import com.liferay.portal.util.PropsValues;
067    import com.liferay.portlet.exportimport.lar.BaseStagedModelDataHandler;
068    import com.liferay.portlet.exportimport.lar.ExportImportPathUtil;
069    import com.liferay.portlet.exportimport.lar.PortletDataContext;
070    import com.liferay.portlet.exportimport.lar.PortletDataException;
071    import com.liferay.portlet.exportimport.lar.PortletDataHandlerKeys;
072    import com.liferay.portlet.exportimport.lar.StagedModelDataHandlerUtil;
073    import com.liferay.portlet.exportimport.lar.StagedModelModifiedDateComparator;
074    import com.liferay.portlet.exportimport.staging.LayoutStagingUtil;
075    import com.liferay.portlet.exportimport.staging.StagingUtil;
076    import com.liferay.portlet.sites.util.SitesUtil;
077    
078    import java.io.IOException;
079    
080    import java.util.Date;
081    import java.util.HashMap;
082    import java.util.List;
083    import java.util.Locale;
084    import java.util.Map;
085    
086    /**
087     * @author Mate Thurzo
088     */
089    @OSGiBeanProperties
090    public class LayoutStagedModelDataHandler
091            extends BaseStagedModelDataHandler<Layout> {
092    
093            public static final String[] CLASS_NAMES = {Layout.class.getName()};
094    
095            @Override
096            public void deleteStagedModel(Layout layout) {
097                    LayoutLocalServiceUtil.deleteLayout(layout);
098            }
099    
100            @Override
101            public void deleteStagedModel(
102                            String uuid, long groupId, String className, String extraData)
103                    throws PortalException {
104    
105                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
106                            extraData);
107    
108                    boolean privateLayout = extraDataJSONObject.getBoolean("privateLayout");
109    
110                    Layout layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
111                            uuid, groupId, privateLayout);
112    
113                    if (layout != null) {
114                            deleteStagedModel(layout);
115                    }
116            }
117    
118            @Override
119            public List<Layout> fetchStagedModelsByUuidAndCompanyId(
120                    String uuid, long companyId) {
121    
122                    return LayoutLocalServiceUtil.getLayoutsByUuidAndCompanyId(
123                            uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
124                            new StagedModelModifiedDateComparator<Layout>());
125            }
126    
127            @Override
128            public String[] getClassNames() {
129                    return CLASS_NAMES;
130            }
131    
132            @Override
133            public String getDisplayName(Layout layout) {
134                    return layout.getNameCurrentValue();
135            }
136    
137            @Override
138            public Map<String, String> getReferenceAttributes(
139                    PortletDataContext portletDataContext, Layout layout) {
140    
141                    Map<String, String> referenceAttributes = new HashMap<>();
142    
143                    referenceAttributes.put(
144                            "private-layout", String.valueOf(layout.isPrivateLayout()));
145                    referenceAttributes.put(
146                            "layout-id", String.valueOf(layout.getLayoutId()));
147    
148                    return referenceAttributes;
149            }
150    
151            @Override
152            public void importMissingReference(
153                            PortletDataContext portletDataContext, Element referenceElement)
154                    throws PortletDataException {
155    
156                    importMissingGroupReference(portletDataContext, referenceElement);
157    
158                    String uuid = referenceElement.attributeValue("uuid");
159    
160                    Map<Long, Long> groupIds =
161                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
162                                    Group.class);
163    
164                    long groupId = GetterUtil.getLong(
165                            referenceElement.attributeValue("group-id"));
166    
167                    groupId = MapUtil.getLong(groupIds, groupId);
168    
169                    boolean privateLayout = GetterUtil.getBoolean(
170                            referenceElement.attributeValue("private-layout"));
171    
172                    Layout existingLayout = null;
173    
174                    existingLayout = fetchMissingReference(uuid, groupId, privateLayout);
175    
176                    Map<Long, Layout> layouts =
177                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
178                                    Layout.class + ".layout");
179    
180                    long layoutId = GetterUtil.getLong(
181                            referenceElement.attributeValue("layout-id"));
182    
183                    layouts.put(layoutId, existingLayout);
184    
185                    Map<Long, Long> layoutPlids =
186                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
187                                    Layout.class);
188    
189                    long plid = GetterUtil.getLong(
190                            referenceElement.attributeValue("class-pk"));
191    
192                    layoutPlids.put(plid, existingLayout.getPlid());
193            }
194    
195            public void setLayoutLocalServiceHelper(
196                    LayoutLocalServiceHelper layoutLocalServiceHelper) {
197    
198                    _layoutLocalServiceHelper = layoutLocalServiceHelper;
199            }
200    
201            @Override
202            public boolean validateReference(
203                    PortletDataContext portletDataContext, Element referenceElement) {
204    
205                    validateMissingGroupReference(portletDataContext, referenceElement);
206    
207                    String uuid = referenceElement.attributeValue("uuid");
208    
209                    Map<Long, Long> groupIds =
210                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
211                                    Group.class);
212    
213                    long groupId = GetterUtil.getLong(
214                            referenceElement.attributeValue("group-id"));
215    
216                    groupId = MapUtil.getLong(groupIds, groupId);
217    
218                    boolean privateLayout = GetterUtil.getBoolean(
219                            referenceElement.attributeValue("private-layout"));
220    
221                    Layout existingLayout = fetchMissingReference(
222                            uuid, groupId, privateLayout);
223    
224                    if (existingLayout == null) {
225                            return false;
226                    }
227    
228                    return true;
229            }
230    
231            protected String[] appendPortletIds(
232                    String[] portletIds, String[] newPortletIds, String portletsMergeMode) {
233    
234                    for (String portletId : newPortletIds) {
235                            if (ArrayUtil.contains(portletIds, portletId)) {
236                                    continue;
237                            }
238    
239                            if (portletsMergeMode.equals(
240                                            PortletDataHandlerKeys.PORTLETS_MERGE_MODE_ADD_TO_BOTTOM)) {
241    
242                                    portletIds = ArrayUtil.append(portletIds, portletId);
243                            }
244                            else {
245                                    portletIds = ArrayUtil.append(
246                                            new String[] {portletId}, portletIds);
247                            }
248                    }
249    
250                    return portletIds;
251            }
252    
253            @Override
254            protected void doExportStagedModel(
255                            PortletDataContext portletDataContext, Layout layout)
256                    throws Exception {
257    
258                    Element layoutElement = portletDataContext.getExportDataElement(layout);
259    
260                    populateElementLayoutMetadata(layoutElement, layout);
261    
262                    layoutElement.addAttribute(Constants.ACTION, Constants.ADD);
263    
264                    portletDataContext.setPlid(layout.getPlid());
265    
266                    long parentLayoutId = layout.getParentLayoutId();
267    
268                    if (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
269                            Layout parentLayout = LayoutLocalServiceUtil.fetchLayout(
270                                    layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
271    
272                            if (parentLayout != null) {
273                                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
274                                            portletDataContext, layout, parentLayout,
275                                            PortletDataContext.REFERENCE_TYPE_PARENT);
276    
277                                    layoutElement.addAttribute(
278                                            "parent-layout-uuid", parentLayout.getUuid());
279                            }
280                    }
281    
282                    List<LayoutFriendlyURL> layoutFriendlyURLs =
283                            LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(
284                                    layout.getPlid());
285    
286                    for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
287                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
288                                    portletDataContext, layout, layoutFriendlyURL,
289                                    PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
290                    }
291    
292                    if (layout.isIconImage()) {
293                            exportLayoutIconImage(portletDataContext, layout, layoutElement);
294                    }
295    
296                    if (layout.isTypeLinkToLayout()) {
297                            exportLinkedLayout(portletDataContext, layout, layoutElement);
298                    }
299    
300                    fixExportTypeSettings(layout);
301    
302                    exportTheme(portletDataContext, layout);
303    
304                    portletDataContext.addClassedModel(
305                            layoutElement, ExportImportPathUtil.getModelPath(layout), layout);
306            }
307    
308            @Override
309            protected void doImportStagedModel(
310                            PortletDataContext portletDataContext, Layout layout)
311                    throws Exception {
312    
313                    long groupId = portletDataContext.getGroupId();
314                    long userId = portletDataContext.getUserId(layout.getUserUuid());
315    
316                    Element layoutElement =
317                            portletDataContext.getImportDataStagedModelElement(layout);
318    
319                    String layoutUuid = GetterUtil.getString(
320                            layoutElement.attributeValue("layout-uuid"));
321    
322                    long layoutId = GetterUtil.getInteger(
323                            layoutElement.attributeValue("layout-id"));
324    
325                    long oldLayoutId = layoutId;
326    
327                    boolean privateLayout = portletDataContext.isPrivateLayout();
328    
329                    String action = layoutElement.attributeValue(Constants.ACTION);
330    
331                    if (action.equals(Constants.DELETE)) {
332                            Layout deletingLayout =
333                                    LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
334                                            layoutUuid, groupId, privateLayout);
335    
336                            LayoutLocalServiceUtil.deleteLayout(
337                                    deletingLayout, false,
338                                    ServiceContextThreadLocal.getServiceContext());
339    
340                            return;
341                    }
342    
343                    Map<Long, Layout> layouts =
344                            (Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
345                                    Layout.class + ".layout");
346    
347                    Layout existingLayout = null;
348                    Layout importedLayout = null;
349    
350                    String friendlyURL = layout.getFriendlyURL();
351    
352                    String layoutsImportMode = MapUtil.getString(
353                            portletDataContext.getParameterMap(),
354                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
355                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID);
356    
357                    if (layoutsImportMode.equals(
358                                    PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_ADD_AS_NEW)) {
359    
360                            layoutId = LayoutLocalServiceUtil.getNextLayoutId(
361                                    groupId, privateLayout);
362                            friendlyURL = StringPool.SLASH + layoutId;
363                    }
364                    else if (layoutsImportMode.equals(
365                                            PortletDataHandlerKeys.
366                                                    LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME)) {
367    
368                            Locale locale = LocaleUtil.getSiteDefault();
369    
370                            String localizedName = layout.getName(locale);
371    
372                            List<Layout> previousLayouts = LayoutLocalServiceUtil.getLayouts(
373                                    groupId, privateLayout);
374    
375                            for (Layout curLayout : previousLayouts) {
376                                    if (localizedName.equals(curLayout.getName(locale)) ||
377                                            friendlyURL.equals(curLayout.getFriendlyURL())) {
378    
379                                            existingLayout = curLayout;
380    
381                                            break;
382                                    }
383                            }
384    
385                            if (existingLayout == null) {
386                                    layoutId = LayoutLocalServiceUtil.getNextLayoutId(
387                                            groupId, privateLayout);
388    
389                                    friendlyURL = getFriendlyURL(friendlyURL, layoutId);
390                            }
391                    }
392                    else if (layoutsImportMode.equals(
393                                            PortletDataHandlerKeys.
394                                                    LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
395    
396                            existingLayout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
397                                    layout.getUuid(), groupId, privateLayout);
398    
399                            if (SitesUtil.isLayoutModifiedSinceLastMerge(existingLayout)) {
400                                    layouts.put(oldLayoutId, existingLayout);
401    
402                                    return;
403                            }
404    
405                            LayoutFriendlyURL layoutFriendlyURL =
406                                    LayoutFriendlyURLLocalServiceUtil.fetchFirstLayoutFriendlyURL(
407                                            groupId, privateLayout, friendlyURL);
408    
409                            if ((layoutFriendlyURL != null) && (existingLayout == null)) {
410                                    Layout mergeFailFriendlyURLLayout =
411                                            LayoutLocalServiceUtil.getLayout(
412                                                    layoutFriendlyURL.getPlid());
413    
414                                    SitesUtil.addMergeFailFriendlyURLLayout(
415                                            mergeFailFriendlyURLLayout);
416    
417                                    if (!_log.isWarnEnabled()) {
418                                            return;
419                                    }
420    
421                                    StringBundler sb = new StringBundler(6);
422    
423                                    sb.append("Layout with layout ID ");
424                                    sb.append(layout.getLayoutId());
425                                    sb.append(" cannot be propagated because the friendly URL ");
426                                    sb.append("conflicts with the friendly URL of layout with ");
427                                    sb.append("layout ID ");
428                                    sb.append(mergeFailFriendlyURLLayout.getLayoutId());
429    
430                                    _log.warn(sb.toString());
431    
432                                    return;
433                            }
434                    }
435                    else {
436    
437                            // The default behavior of import mode is
438                            // PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID
439    
440                            existingLayout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
441                                    layout.getUuid(), groupId, privateLayout);
442    
443                            if (existingLayout == null) {
444                                    existingLayout =
445                                            LayoutLocalServiceUtil.fetchLayoutByFriendlyURL(
446                                                    groupId, privateLayout, friendlyURL);
447                            }
448    
449                            if (existingLayout == null) {
450                                    layoutId = LayoutLocalServiceUtil.getNextLayoutId(
451                                            groupId, privateLayout);
452    
453                                    friendlyURL = getFriendlyURL(friendlyURL, layoutId);
454                            }
455                    }
456    
457                    if (_log.isDebugEnabled()) {
458                            StringBundler sb = new StringBundler(7);
459    
460                            sb.append("Layout with {groupId=");
461                            sb.append(groupId);
462                            sb.append(",privateLayout=");
463                            sb.append(privateLayout);
464                            sb.append(",layoutId=");
465                            sb.append(layoutId);
466    
467                            if (existingLayout == null) {
468                                    sb.append("} does not exist");
469    
470                                    _log.debug(sb.toString());
471                            }
472                            else {
473                                    sb.append("} exists");
474    
475                                    _log.debug(sb.toString());
476                            }
477                    }
478    
479                    if (existingLayout == null) {
480                            long plid = CounterLocalServiceUtil.increment();
481    
482                            importedLayout = LayoutLocalServiceUtil.createLayout(plid);
483    
484                            if (layoutsImportMode.equals(
485                                            PortletDataHandlerKeys.
486                                                    LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
487    
488                                    importedLayout.setSourcePrototypeLayoutUuid(layout.getUuid());
489    
490                                    layoutId = LayoutLocalServiceUtil.getNextLayoutId(
491                                            groupId, privateLayout);
492    
493                                    friendlyURL = getFriendlyURL(friendlyURL, layoutId);
494                            }
495                            else {
496                                    importedLayout.setCreateDate(layout.getCreateDate());
497                                    importedLayout.setModifiedDate(layout.getModifiedDate());
498                                    importedLayout.setLayoutPrototypeUuid(
499                                            layout.getLayoutPrototypeUuid());
500                                    importedLayout.setLayoutPrototypeLinkEnabled(
501                                            layout.isLayoutPrototypeLinkEnabled());
502                                    importedLayout.setSourcePrototypeLayoutUuid(
503                                            layout.getSourcePrototypeLayoutUuid());
504                            }
505    
506                            importedLayout.setUuid(layout.getUuid());
507                            importedLayout.setGroupId(groupId);
508                            importedLayout.setUserId(userId);
509                            importedLayout.setPrivateLayout(privateLayout);
510                            importedLayout.setLayoutId(layoutId);
511    
512                            initNewLayoutPermissions(
513                                    portletDataContext.getCompanyId(), groupId, userId, layout,
514                                    importedLayout, privateLayout);
515    
516                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
517                                    groupId, privateLayout);
518    
519                            importedLayout.setLayoutSet(layoutSet);
520                    }
521                    else {
522                            importedLayout = existingLayout;
523                    }
524    
525                    portletDataContext.setPlid(importedLayout.getPlid());
526                    portletDataContext.setOldPlid(layout.getPlid());
527    
528                    long parentLayoutId = layout.getParentLayoutId();
529    
530                    String parentLayoutUuid = GetterUtil.getString(
531                            layoutElement.attributeValue("parent-layout-uuid"));
532    
533                    Element parentLayoutElement =
534                            portletDataContext.getReferenceDataElement(
535                                    layout, Layout.class, layout.getGroupId(), parentLayoutUuid);
536    
537                    if ((parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) &&
538                            (parentLayoutElement != null)) {
539    
540                            StagedModelDataHandlerUtil.importStagedModel(
541                                    portletDataContext, parentLayoutElement);
542    
543                            Layout importedParentLayout = layouts.get(parentLayoutId);
544    
545                            parentLayoutId = importedParentLayout.getLayoutId();
546                    }
547    
548                    if (_log.isDebugEnabled()) {
549                            StringBundler sb = new StringBundler(4);
550    
551                            sb.append("Importing layout with layout id ");
552                            sb.append(layoutId);
553                            sb.append(" and parent layout id ");
554                            sb.append(parentLayoutId);
555    
556                            _log.debug(sb.toString());
557                    }
558    
559                    importedLayout.setCompanyId(portletDataContext.getCompanyId());
560    
561                    if (layout.getLayoutPrototypeUuid() != null) {
562                            importedLayout.setModifiedDate(new Date());
563                    }
564    
565                    importedLayout.setParentLayoutId(parentLayoutId);
566                    importedLayout.setName(layout.getName());
567                    importedLayout.setTitle(layout.getTitle());
568                    importedLayout.setDescription(layout.getDescription());
569                    importedLayout.setKeywords(layout.getKeywords());
570                    importedLayout.setRobots(layout.getRobots());
571                    importedLayout.setType(layout.getType());
572    
573                    String portletsMergeMode = MapUtil.getString(
574                            portletDataContext.getParameterMap(),
575                            PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
576                            PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE);
577    
578                    if (layout.isTypePortlet() &&
579                            Validator.isNotNull(layout.getTypeSettings()) &&
580                            !portletsMergeMode.equals(
581                                    PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE)) {
582    
583                            mergePortlets(
584                                    importedLayout, layout.getTypeSettings(), portletsMergeMode);
585                    }
586                    else if (layout.isTypeLinkToLayout()) {
587                            importLinkedLayout(
588                                    portletDataContext, layout, importedLayout, layoutElement,
589                                    layouts);
590                    }
591                    else {
592                            updateTypeSettings(importedLayout, layout);
593                    }
594    
595                    importedLayout.setHidden(layout.isHidden());
596                    importedLayout.setFriendlyURL(
597                            getUniqueFriendlyURL(
598                                    portletDataContext, importedLayout, friendlyURL));
599    
600                    if (layout.getIconImageId() > 0) {
601                            importLayoutIconImage(
602                                    portletDataContext, importedLayout, layoutElement);
603                    }
604                    else if (importedLayout.getIconImageId() > 0) {
605                            ImageLocalServiceUtil.deleteImage(importedLayout.getIconImageId());
606                    }
607    
608                    if (existingLayout == null) {
609                            int priority = _layoutLocalServiceHelper.getNextPriority(
610                                    groupId, privateLayout, parentLayoutId, null, -1);
611    
612                            importedLayout.setPriority(priority);
613                    }
614    
615                    importedLayout.setLayoutPrototypeUuid(layout.getLayoutPrototypeUuid());
616                    importedLayout.setLayoutPrototypeLinkEnabled(
617                            layout.isLayoutPrototypeLinkEnabled());
618    
619                    ServiceContext serviceContext = portletDataContext.createServiceContext(
620                            layout);
621    
622                    importedLayout.setExpandoBridgeAttributes(serviceContext);
623    
624                    StagingUtil.updateLastImportSettings(
625                            layoutElement, importedLayout, portletDataContext);
626    
627                    fixImportTypeSettings(importedLayout);
628    
629                    importTheme(portletDataContext, layout, importedLayout);
630    
631                    LayoutLocalServiceUtil.updateLayout(importedLayout);
632    
633                    LayoutSetLocalServiceUtil.updatePageCount(groupId, privateLayout);
634    
635                    Map<Long, Long> layoutPlids =
636                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
637                                    Layout.class);
638    
639                    layoutPlids.put(layout.getPlid(), importedLayout.getPlid());
640    
641                    layouts.put(oldLayoutId, importedLayout);
642    
643                    importAssets(portletDataContext, layout, importedLayout);
644    
645                    importLayoutFriendlyURLs(portletDataContext, layout);
646    
647                    portletDataContext.importClassedModel(layout, importedLayout);
648            }
649    
650            protected void exportLayoutIconImage(
651                            PortletDataContext portletDataContext, Layout layout,
652                            Element layoutElement)
653                    throws Exception {
654    
655                    Image image = ImageLocalServiceUtil.getImage(layout.getIconImageId());
656    
657                    if (image != null) {
658                            String iconPath = ExportImportPathUtil.getModelPath(
659                                    portletDataContext.getScopeGroupId(), Image.class.getName(),
660                                    image.getImageId());
661    
662                            Element iconImagePathElement = layoutElement.addElement(
663                                    "icon-image-path");
664    
665                            iconImagePathElement.addText(iconPath);
666    
667                            portletDataContext.addZipEntry(iconPath, image.getTextObj());
668                    }
669            }
670    
671            protected void exportLinkedLayout(
672                            PortletDataContext portletDataContext, Layout layout,
673                            Element layoutElement)
674                    throws Exception {
675    
676                    UnicodeProperties typeSettingsProperties =
677                            layout.getTypeSettingsProperties();
678    
679                    long linkToLayoutId = GetterUtil.getLong(
680                            typeSettingsProperties.getProperty(
681                                    "linkToLayoutId", StringPool.BLANK));
682    
683                    if (linkToLayoutId > 0) {
684                            try {
685                                    Layout linkedToLayout = LayoutLocalServiceUtil.getLayout(
686                                            portletDataContext.getScopeGroupId(),
687                                            layout.isPrivateLayout(), linkToLayoutId);
688    
689                                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
690                                            portletDataContext, layout, linkedToLayout,
691                                            PortletDataContext.REFERENCE_TYPE_STRONG);
692    
693                                    layoutElement.addAttribute(
694                                            "linked-to-layout-uuid", linkedToLayout.getUuid());
695                            }
696                            catch (NoSuchLayoutException nsle) {
697                            }
698                    }
699            }
700    
701            protected void exportTheme(
702                            PortletDataContext portletDataContext, Layout layout)
703                    throws Exception {
704    
705                    boolean exportThemeSettings = MapUtil.getBoolean(
706                            portletDataContext.getParameterMap(),
707                            PortletDataHandlerKeys.THEME_REFERENCE);
708    
709                    if (_log.isDebugEnabled()) {
710                            _log.debug("Export theme settings " + exportThemeSettings);
711                    }
712    
713                    if (exportThemeSettings &&
714                            !portletDataContext.isPerformDirectBinaryImport() &&
715                            !layout.isInheritLookAndFeel()) {
716    
717                            StagedTheme stagedTheme = new StagedThemeImpl(layout.getTheme());
718    
719                            Element layoutElement = portletDataContext.getExportDataElement(
720                                    layout);
721    
722                            portletDataContext.addReferenceElement(
723                                    layout, layoutElement, stagedTheme,
724                                    PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
725                    }
726            }
727    
728            protected Object[] extractFriendlyURLInfo(Layout layout) {
729                    if (!layout.isTypeURL()) {
730                            return null;
731                    }
732    
733                    UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
734    
735                    String url = GetterUtil.getString(typeSettings.getProperty("url"));
736    
737                    String friendlyURLPrivateGroupPath =
738                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
739                    String friendlyURLPrivateUserPath =
740                            PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
741                    String friendlyURLPublicPath =
742                            PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
743    
744                    if (!url.startsWith(friendlyURLPrivateGroupPath) &&
745                            !url.startsWith(friendlyURLPrivateUserPath) &&
746                            !url.startsWith(friendlyURLPublicPath)) {
747    
748                            return null;
749                    }
750    
751                    int x = url.indexOf(CharPool.SLASH, 1);
752    
753                    if (x == -1) {
754                            return null;
755                    }
756    
757                    int y = url.indexOf(CharPool.SLASH, x + 1);
758    
759                    if (y == -1) {
760                            return null;
761                    }
762    
763                    return new Object[] {url.substring(x, y), url, x, y};
764            }
765    
766            protected Layout fetchMissingReference(
767                    String uuid, long groupId, boolean privateLayout) {
768    
769                    // Try to fetch the existing layout from the importing group
770    
771                    Layout layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
772                            uuid, groupId, privateLayout);
773    
774                    if (layout != null) {
775                            return layout;
776                    }
777    
778                    try {
779    
780                            // Try to fetch the existing layout from the parent sites
781    
782                            Group originalGroup = GroupLocalServiceUtil.getGroup(groupId);
783    
784                            Group group = originalGroup.getParentGroup();
785    
786                            while (group != null) {
787                                    layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
788                                            uuid, group.getGroupId(), privateLayout);
789    
790                                    if (layout != null) {
791                                            break;
792                                    }
793    
794                                    group = group.getParentGroup();
795                            }
796    
797                            if (layout == null) {
798                                    List<Layout> layouts = fetchStagedModelsByUuidAndCompanyId(
799                                            uuid, originalGroup.getCompanyId());
800    
801                                    if (ListUtil.isEmpty(layouts)) {
802                                            return null;
803                                    }
804    
805                                    layout = layouts.get(0);
806                            }
807    
808                            return layout;
809                    }
810                    catch (Exception e) {
811                            if (_log.isDebugEnabled()) {
812                                    _log.debug(e, e);
813                            }
814                            else if (_log.isWarnEnabled()) {
815                                    _log.warn(
816                                            "Unable to fetch missing reference layout from group " +
817                                                    groupId);
818                            }
819    
820                            return null;
821                    }
822            }
823    
824            protected void fixExportTypeSettings(Layout layout) throws Exception {
825                    Object[] friendlyURLInfo = extractFriendlyURLInfo(layout);
826    
827                    if (friendlyURLInfo == null) {
828                            return;
829                    }
830    
831                    String friendlyURL = (String)friendlyURLInfo[0];
832    
833                    Group group = layout.getGroup();
834    
835                    String groupFriendlyURL = group.getFriendlyURL();
836    
837                    if (!friendlyURL.equals(groupFriendlyURL)) {
838                            return;
839                    }
840    
841                    UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
842    
843                    String url = (String)friendlyURLInfo[1];
844    
845                    int x = (Integer)friendlyURLInfo[2];
846                    int y = (Integer)friendlyURLInfo[3];
847    
848                    typeSettings.setProperty(
849                            "url",
850                            url.substring(0, x) + _SAME_GROUP_FRIENDLY_URL + url.substring(y));
851            }
852    
853            protected void fixImportTypeSettings(Layout layout) throws Exception {
854                    Object[] friendlyURLInfo = extractFriendlyURLInfo(layout);
855    
856                    if (friendlyURLInfo == null) {
857                            return;
858                    }
859    
860                    String friendlyURL = (String)friendlyURLInfo[0];
861    
862                    if (!friendlyURL.equals(_SAME_GROUP_FRIENDLY_URL)) {
863                            return;
864                    }
865    
866                    Group group = layout.getGroup();
867    
868                    UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
869    
870                    String url = (String)friendlyURLInfo[1];
871    
872                    int x = (Integer)friendlyURLInfo[2];
873                    int y = (Integer)friendlyURLInfo[3];
874    
875                    typeSettings.setProperty(
876                            "url",
877                            url.substring(0, x) + group.getFriendlyURL() + url.substring(y));
878            }
879    
880            protected String getFriendlyURL(String friendlyURL, long layoutId) {
881                    if (!Validator.isNumber(friendlyURL.substring(1))) {
882                            return friendlyURL;
883                    }
884    
885                    return StringPool.SLASH + layoutId;
886            }
887    
888            protected String getUniqueFriendlyURL(
889                    PortletDataContext portletDataContext, Layout existingLayout,
890                    String friendlyURL) {
891    
892                    for (int i = 1;; i++) {
893                            Layout duplicateFriendlyURLLayout =
894                                    LayoutLocalServiceUtil.fetchLayoutByFriendlyURL(
895                                            portletDataContext.getGroupId(),
896                                            portletDataContext.isPrivateLayout(), friendlyURL);
897    
898                            if ((duplicateFriendlyURLLayout == null) ||
899                                    (duplicateFriendlyURLLayout.getPlid() ==
900                                            existingLayout.getPlid())) {
901    
902                                    break;
903                            }
904    
905                            friendlyURL = friendlyURL + i;
906                    }
907    
908                    return friendlyURL;
909            }
910    
911            protected void importAssets(
912                            PortletDataContext portletDataContext, Layout layout,
913                            Layout importedLayout)
914                    throws Exception {
915    
916                    long userId = portletDataContext.getUserId(layout.getUserUuid());
917    
918                    long[] assetCategoryIds = portletDataContext.getAssetCategoryIds(
919                            Layout.class, layout.getPlid());
920                    String[] assetTagNames = portletDataContext.getAssetTagNames(
921                            Layout.class, layout.getPlid());
922    
923                    LayoutLocalServiceUtil.updateAsset(
924                            userId, importedLayout, assetCategoryIds, assetTagNames);
925            }
926    
927            protected void importLayoutFriendlyURLs(
928                            PortletDataContext portletDataContext, Layout layout)
929                    throws Exception {
930    
931                    List<Element> layoutFriendlyURLElements =
932                            portletDataContext.getReferenceDataElements(
933                                    layout, LayoutFriendlyURL.class);
934    
935                    for (Element layoutFriendlyURLElement : layoutFriendlyURLElements) {
936                            String layoutFriendlyURLPath =
937                                    layoutFriendlyURLElement.attributeValue("path");
938    
939                            LayoutFriendlyURL layoutFriendlyURL =
940                                    (LayoutFriendlyURL)portletDataContext.getZipEntryAsObject(
941                                            layoutFriendlyURLPath);
942    
943                            StagedModelDataHandlerUtil.importStagedModel(
944                                    portletDataContext, layoutFriendlyURL);
945                    }
946            }
947    
948            protected void importLayoutIconImage(
949                            PortletDataContext portletDataContext, Layout importedLayout,
950                            Element layoutElement)
951                    throws Exception {
952    
953                    String iconImagePath = layoutElement.elementText("icon-image-path");
954    
955                    byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
956                            iconImagePath);
957    
958                    if (ArrayUtil.isNotEmpty(iconBytes)) {
959                            if (importedLayout.getIconImageId() == 0) {
960                                    long iconImageId = CounterLocalServiceUtil.increment();
961    
962                                    importedLayout.setIconImageId(iconImageId);
963                            }
964    
965                            ImageLocalServiceUtil.updateImage(
966                                    importedLayout.getIconImageId(), iconBytes);
967                    }
968            }
969    
970            protected void importLinkedLayout(
971                            PortletDataContext portletDataContext, Layout layout,
972                            Layout importedLayout, Element layoutElement,
973                            Map<Long, Layout> layouts)
974                    throws Exception {
975    
976                    UnicodeProperties typeSettingsProperties =
977                            layout.getTypeSettingsProperties();
978    
979                    long linkToLayoutId = GetterUtil.getLong(
980                            typeSettingsProperties.getProperty(
981                                    "linkToLayoutId", StringPool.BLANK));
982    
983                    String linkedToLayoutUuid = layoutElement.attributeValue(
984                            "linked-to-layout-uuid");
985    
986                    if (Validator.isNull(linkedToLayoutUuid)) {
987                            return;
988                    }
989    
990                    if (linkToLayoutId <= 0) {
991                            updateTypeSettings(importedLayout, layout);
992    
993                            return;
994                    }
995    
996                    Element linkedToLayoutElement =
997                            portletDataContext.getReferenceDataElement(
998                                    layout, Layout.class, layout.getGroupId(), linkedToLayoutUuid);
999    
1000                    if (linkedToLayoutElement != null) {
1001                            String linkedToLayoutPath = linkedToLayoutElement.attributeValue(
1002                                    "path");
1003    
1004                            Layout linkedToLayout =
1005                                    (Layout)portletDataContext.getZipEntryAsObject(
1006                                            linkedToLayoutPath);
1007    
1008                            StagedModelDataHandlerUtil.importStagedModel(
1009                                    portletDataContext, linkedToLayout);
1010    
1011                            Layout importedLinkedLayout = layouts.get(linkToLayoutId);
1012    
1013                            typeSettingsProperties.setProperty(
1014                                    "privateLayout",
1015                                    String.valueOf(importedLinkedLayout.isPrivateLayout()));
1016                            typeSettingsProperties.setProperty(
1017                                    "linkToLayoutId",
1018                                    String.valueOf(importedLinkedLayout.getLayoutId()));
1019                    }
1020                    else {
1021                            if (_log.isWarnEnabled()) {
1022                                    StringBundler sb = new StringBundler(6);
1023    
1024                                    sb.append("Unable to link layout with friendly URL ");
1025                                    sb.append(layout.getFriendlyURL());
1026                                    sb.append(" and layout id ");
1027                                    sb.append(layout.getLayoutId());
1028                                    sb.append(" to layout with layout id ");
1029                                    sb.append(linkToLayoutId);
1030    
1031                                    _log.warn(sb.toString());
1032                            }
1033                    }
1034    
1035                    updateTypeSettings(importedLayout, layout);
1036            }
1037    
1038            @Override
1039            protected void importReferenceStagedModels(
1040                    PortletDataContext portletDataContext, Layout layout) {
1041            }
1042    
1043            protected void importTheme(
1044                            PortletDataContext portletDataContext, Layout layout,
1045                            Layout importedLayout)
1046                    throws Exception {
1047    
1048                    boolean importThemeSettings = MapUtil.getBoolean(
1049                            portletDataContext.getParameterMap(),
1050                            PortletDataHandlerKeys.THEME_REFERENCE);
1051    
1052                    if (_log.isDebugEnabled()) {
1053                            _log.debug("Import theme settings " + importThemeSettings);
1054                    }
1055    
1056                    if (importThemeSettings) {
1057                            importedLayout.setColorSchemeId(layout.getColorSchemeId());
1058                            importedLayout.setCss(layout.getCss());
1059                            importedLayout.setThemeId(layout.getThemeId());
1060                            importedLayout.setWapColorSchemeId(layout.getWapColorSchemeId());
1061                            importedLayout.setWapThemeId(layout.getWapThemeId());
1062                    }
1063                    else {
1064                            importedLayout.setColorSchemeId(StringPool.BLANK);
1065                            importedLayout.setCss(StringPool.BLANK);
1066                            importedLayout.setThemeId(StringPool.BLANK);
1067                            importedLayout.setWapColorSchemeId(StringPool.BLANK);
1068                            importedLayout.setWapThemeId(StringPool.BLANK);
1069                    }
1070            }
1071    
1072            protected void initNewLayoutPermissions(
1073                            long companyId, long groupId, long userId, Layout layout,
1074                            Layout importedLayout, boolean privateLayout)
1075                    throws Exception {
1076    
1077                    boolean addGroupPermissions = true;
1078    
1079                    Group group = importedLayout.getGroup();
1080    
1081                    if (privateLayout && group.isUser()) {
1082                            addGroupPermissions = false;
1083                    }
1084    
1085                    boolean addGuestPermissions = false;
1086    
1087                    if (!privateLayout || layout.isTypeControlPanel()) {
1088                            addGuestPermissions = true;
1089                    }
1090    
1091                    ResourceLocalServiceUtil.addResources(
1092                            companyId, groupId, userId, Layout.class.getName(),
1093                            importedLayout.getPlid(), false, addGroupPermissions,
1094                            addGuestPermissions);
1095            }
1096    
1097            protected void mergePortlets(
1098                    Layout layout, String newTypeSettings, String portletsMergeMode) {
1099    
1100                    try {
1101                            UnicodeProperties previousTypeSettingsProperties =
1102                                    layout.getTypeSettingsProperties();
1103    
1104                            LayoutTypePortlet previousLayoutType =
1105                                    (LayoutTypePortlet)layout.getLayoutType();
1106    
1107                            LayoutTemplate previousLayoutTemplate =
1108                                    previousLayoutType.getLayoutTemplate();
1109    
1110                            List<String> previousColumns = previousLayoutTemplate.getColumns();
1111    
1112                            UnicodeProperties newTypeSettingsProperties = new UnicodeProperties(
1113                                    true);
1114    
1115                            newTypeSettingsProperties.load(newTypeSettings);
1116    
1117                            String layoutTemplateId = newTypeSettingsProperties.getProperty(
1118                                    LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID);
1119    
1120                            previousTypeSettingsProperties.setProperty(
1121                                    LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID,
1122                                    layoutTemplateId);
1123    
1124                            String nestedColumnIds = newTypeSettingsProperties.getProperty(
1125                                    LayoutTypePortletConstants.NESTED_COLUMN_IDS);
1126    
1127                            if (Validator.isNotNull(nestedColumnIds)) {
1128                                    previousTypeSettingsProperties.setProperty(
1129                                            LayoutTypePortletConstants.NESTED_COLUMN_IDS,
1130                                            nestedColumnIds);
1131    
1132                                    String[] nestedColumnIdsArray = StringUtil.split(
1133                                            nestedColumnIds);
1134    
1135                                    for (String nestedColumnId : nestedColumnIdsArray) {
1136                                            String nestedColumnValue =
1137                                                    newTypeSettingsProperties.getProperty(nestedColumnId);
1138    
1139                                            previousTypeSettingsProperties.setProperty(
1140                                                    nestedColumnId, nestedColumnValue);
1141                                    }
1142                            }
1143    
1144                            LayoutTemplate newLayoutTemplate =
1145                                    LayoutTemplateLocalServiceUtil.getLayoutTemplate(
1146                                            layoutTemplateId, false, null);
1147    
1148                            String[] newPortletIds = new String[0];
1149    
1150                            for (String columnId : newLayoutTemplate.getColumns()) {
1151                                    String columnValue = newTypeSettingsProperties.getProperty(
1152                                            columnId);
1153    
1154                                    String[] portletIds = StringUtil.split(columnValue);
1155    
1156                                    if (!previousColumns.contains(columnId)) {
1157                                            newPortletIds = ArrayUtil.append(newPortletIds, portletIds);
1158                                    }
1159                                    else {
1160                                            String[] previousPortletIds = StringUtil.split(
1161                                                    previousTypeSettingsProperties.getProperty(columnId));
1162    
1163                                            portletIds = appendPortletIds(
1164                                                    previousPortletIds, portletIds, portletsMergeMode);
1165    
1166                                            previousTypeSettingsProperties.setProperty(
1167                                                    columnId, StringUtil.merge(portletIds));
1168                                    }
1169                            }
1170    
1171                            // Add portlets in non-existent column to the first column
1172    
1173                            String columnId = previousColumns.get(0);
1174    
1175                            String[] portletIds = StringUtil.split(
1176                                    previousTypeSettingsProperties.getProperty(columnId));
1177    
1178                            appendPortletIds(portletIds, newPortletIds, portletsMergeMode);
1179    
1180                            previousTypeSettingsProperties.setProperty(
1181                                    columnId, StringUtil.merge(portletIds));
1182    
1183                            layout.setTypeSettings(previousTypeSettingsProperties.toString());
1184                    }
1185                    catch (IOException ioe) {
1186                            layout.setTypeSettings(newTypeSettings);
1187                    }
1188            }
1189    
1190            protected void populateElementLayoutMetadata(
1191                            Element layoutElement, Layout layout)
1192                    throws Exception {
1193    
1194                    LayoutStagingHandler layoutStagingHandler =
1195                            LayoutStagingUtil.getLayoutStagingHandler(layout);
1196    
1197                    if (layoutStagingHandler != null) {
1198                            LayoutRevision layoutRevision =
1199                                    layoutStagingHandler.getLayoutRevision();
1200    
1201                            if (layoutRevision != null) {
1202                                    layoutElement.addAttribute(
1203                                            "layout-revision-id",
1204                                            String.valueOf(layoutRevision.getLayoutRevisionId()));
1205                                    layoutElement.addAttribute(
1206                                            "layout-branch-id",
1207                                            String.valueOf(layoutRevision.getLayoutBranchId()));
1208    
1209                                    LayoutBranch layoutBranch = layoutRevision.getLayoutBranch();
1210    
1211                                    layoutElement.addAttribute(
1212                                            "layout-branch-name",
1213                                            String.valueOf(layoutBranch.getName()));
1214                            }
1215                    }
1216    
1217                    layoutElement.addAttribute("layout-uuid", layout.getUuid());
1218                    layoutElement.addAttribute(
1219                            "layout-id", String.valueOf(layout.getLayoutId()));
1220                    layoutElement.addAttribute(
1221                            "layout-priority", String.valueOf(layout.getPriority()));
1222    
1223                    String layoutPrototypeUuid = layout.getLayoutPrototypeUuid();
1224    
1225                    if (Validator.isNotNull(layoutPrototypeUuid)) {
1226                            LayoutPrototype layoutPrototype =
1227                                    LayoutPrototypeLocalServiceUtil.
1228                                            getLayoutPrototypeByUuidAndCompanyId(
1229                                                    layoutPrototypeUuid, layout.getCompanyId());
1230    
1231                            layoutElement.addAttribute(
1232                                    "layout-prototype-uuid", layoutPrototypeUuid);
1233                            layoutElement.addAttribute(
1234                                    "layout-prototype-name",
1235                                    layoutPrototype.getName(LocaleUtil.getDefault()));
1236                    }
1237            }
1238    
1239            protected void updateTypeSettings(Layout importedLayout, Layout layout)
1240                    throws PortalException {
1241    
1242                    long groupId = layout.getGroupId();
1243    
1244                    try {
1245                            LayoutTypePortlet importedLayoutType =
1246                                    (LayoutTypePortlet)importedLayout.getLayoutType();
1247    
1248                            List<String> importedPortletIds =
1249                                    importedLayoutType.getPortletIds();
1250    
1251                            layout.setGroupId(importedLayout.getGroupId());
1252    
1253                            LayoutTypePortlet layoutTypePortlet =
1254                                    (LayoutTypePortlet)layout.getLayoutType();
1255    
1256                            importedPortletIds.removeAll(layoutTypePortlet.getPortletIds());
1257    
1258                            if (!importedPortletIds.isEmpty()) {
1259                                    PortletLocalServiceUtil.deletePortlets(
1260                                            importedLayout.getCompanyId(),
1261                                            importedPortletIds.toArray(
1262                                                    new String[importedPortletIds.size()]),
1263                                            importedLayout.getPlid());
1264                            }
1265    
1266                            importedLayout.setTypeSettingsProperties(
1267                                    layoutTypePortlet.getTypeSettingsProperties());
1268                    }
1269                    finally {
1270                            layout.setGroupId(groupId);
1271                    }
1272            }
1273    
1274            private static final String _SAME_GROUP_FRIENDLY_URL =
1275                    "/[$SAME_GROUP_FRIENDLY_URL$]";
1276    
1277            private static final Log _log = LogFactoryUtil.getLog(
1278                    LayoutStagedModelDataHandler.class);
1279    
1280            private static LayoutLocalServiceHelper _layoutLocalServiceHelper;
1281    
1282    }