protected PortletPreferences getPortletPreferences(
      ThemeDisplay themeDisplay, String portletId, String settingsScope) {

    Layout layout = themeDisplay.getLayout();

    if (!layout.isSupportsEmbeddedPortlets()) {
      return null;
    }

    LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

    if (!layoutTypePortlet.isPortletEmbedded(portletId)) {
      return null;
    }

    PortletPreferencesIds portletPreferencesIds =
        new PortletPreferencesIds(
            themeDisplay.getCompanyId(),
            layout.getGroupId(),
            PortletKeys.PREFS_OWNER_TYPE_LAYOUT,
            PortletKeys.PREFS_PLID_SHARED,
            portletId);

    return _portletPreferencesLocalService.getPreferences(portletPreferencesIds);
  }
  private static void _addLayoutBreadcrumbEntries(
      List<BreadcrumbEntry> breadcrumbEntries, ThemeDisplay themeDisplay, Layout layout)
      throws Exception {

    if (layout.getParentLayoutId() != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {

      Layout parentLayout = LayoutLocalServiceUtil.getParentLayout(layout);

      _addLayoutBreadcrumbEntries(breadcrumbEntries, themeDisplay, parentLayout);
    }

    BreadcrumbEntry breadcrumbEntry = new BreadcrumbEntry();

    breadcrumbEntry.setBaseModel(layout);

    LayoutType layoutType = layout.getLayoutType();

    if (!layoutType.isBrowsable()) {
      breadcrumbEntry.setBrowsable(false);
    }

    String layoutName = layout.getName(themeDisplay.getLocale());

    if (layout.isTypeControlPanel()) {
      if (layoutName.equals(LayoutConstants.NAME_CONTROL_PANEL_DEFAULT)) {
        layoutName = LanguageUtil.get(themeDisplay.getLocale(), "control-panel");
      }
    }

    breadcrumbEntry.setTitle(layoutName);

    String layoutURL = PortalUtil.getLayoutFullURL(layout, themeDisplay);

    if (themeDisplay.isAddSessionIdToURL()) {
      layoutURL = PortalUtil.getURLWithSessionId(layoutURL, themeDisplay.getSessionId());
    }

    breadcrumbEntry.setURL(layoutURL);

    breadcrumbEntries.add(breadcrumbEntry);
  }
  public void addLayout(ActionRequest actionRequest, ActionResponse actionResponse)
      throws Exception {

    UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(actionRequest);

    ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);

    long groupId = ParamUtil.getLong(actionRequest, "groupId");
    long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
    long stagingGroupId = ParamUtil.getLong(actionRequest, "stagingGroupId");
    boolean privateLayout = ParamUtil.getBoolean(actionRequest, "privateLayout");
    long parentLayoutId = ParamUtil.getLong(uploadPortletRequest, "parentLayoutId");
    Map<Locale, String> nameMap = LocalizationUtil.getLocalizationMap(actionRequest, "name");
    Map<Locale, String> titleMap = LocalizationUtil.getLocalizationMap(actionRequest, "title");
    Map<Locale, String> descriptionMap =
        LocalizationUtil.getLocalizationMap(actionRequest, "description");
    Map<Locale, String> keywordsMap =
        LocalizationUtil.getLocalizationMap(actionRequest, "keywords");
    Map<Locale, String> robotsMap = LocalizationUtil.getLocalizationMap(actionRequest, "robots");
    String type = ParamUtil.getString(uploadPortletRequest, "type");
    boolean hidden = ParamUtil.getBoolean(uploadPortletRequest, "hidden");
    Map<Locale, String> friendlyURLMap =
        LocalizationUtil.getLocalizationMap(actionRequest, "friendlyURL");

    long layoutPrototypeId = ParamUtil.getLong(uploadPortletRequest, "layoutPrototypeId");

    ServiceContext serviceContext =
        ServiceContextFactory.getInstance(Layout.class.getName(), actionRequest);

    Layout layout = null;

    boolean inheritFromParentLayoutId =
        ParamUtil.getBoolean(uploadPortletRequest, "inheritFromParentLayoutId");

    UnicodeProperties typeSettingsProperties =
        PropertiesParamUtil.getProperties(actionRequest, "TypeSettingsProperties--");

    if (inheritFromParentLayoutId && (parentLayoutId > 0)) {
      Layout parentLayout = layoutLocalService.getLayout(groupId, privateLayout, parentLayoutId);

      layout =
          layoutService.addLayout(
              groupId,
              privateLayout,
              parentLayoutId,
              nameMap,
              titleMap,
              parentLayout.getDescriptionMap(),
              parentLayout.getKeywordsMap(),
              parentLayout.getRobotsMap(),
              parentLayout.getType(),
              parentLayout.getTypeSettings(),
              hidden,
              friendlyURLMap,
              serviceContext);

      inheritMobileRuleGroups(layout, serviceContext);

      if (parentLayout.isTypePortlet()) {
        ActionUtil.copyPreferences(actionRequest, layout, parentLayout);

        SitesUtil.copyLookAndFeel(layout, parentLayout);
      }
    } else if (layoutPrototypeId > 0) {
      LayoutPrototype layoutPrototype =
          layoutPrototypeService.getLayoutPrototype(layoutPrototypeId);

      boolean layoutPrototypeLinkEnabled =
          ParamUtil.getBoolean(
              uploadPortletRequest, "layoutPrototypeLinkEnabled" + layoutPrototype.getUuid());

      serviceContext.setAttribute("layoutPrototypeLinkEnabled", layoutPrototypeLinkEnabled);

      serviceContext.setAttribute("layoutPrototypeUuid", layoutPrototype.getUuid());

      layout =
          layoutService.addLayout(
              groupId,
              privateLayout,
              parentLayoutId,
              nameMap,
              titleMap,
              descriptionMap,
              keywordsMap,
              robotsMap,
              LayoutConstants.TYPE_PORTLET,
              typeSettingsProperties.toString(),
              hidden,
              friendlyURLMap,
              serviceContext);

      // Force propagation from page template to page.
      // See LPS-48430.

      SitesUtil.mergeLayoutPrototypeLayout(layout.getGroup(), layout);
    } else {
      long copyLayoutId = ParamUtil.getLong(uploadPortletRequest, "copyLayoutId");

      Layout copyLayout = null;

      String layoutTemplateId =
          ParamUtil.getString(
              uploadPortletRequest, "layoutTemplateId", PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID);

      if (copyLayoutId > 0) {
        copyLayout = layoutLocalService.fetchLayout(groupId, privateLayout, copyLayoutId);

        if ((copyLayout != null) && copyLayout.isTypePortlet()) {
          LayoutTypePortlet copyLayoutTypePortlet = (LayoutTypePortlet) copyLayout.getLayoutType();

          layoutTemplateId = copyLayoutTypePortlet.getLayoutTemplateId();

          typeSettingsProperties = copyLayout.getTypeSettingsProperties();
        }
      }

      layout =
          layoutService.addLayout(
              groupId,
              privateLayout,
              parentLayoutId,
              nameMap,
              titleMap,
              descriptionMap,
              keywordsMap,
              robotsMap,
              type,
              typeSettingsProperties.toString(),
              hidden,
              friendlyURLMap,
              serviceContext);

      LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

      layoutTypePortlet.setLayoutTemplateId(themeDisplay.getUserId(), layoutTemplateId);

      layoutService.updateLayout(
          groupId, privateLayout, layout.getLayoutId(), layout.getTypeSettings());

      if ((copyLayout != null) && copyLayout.isTypePortlet()) {
        ActionUtil.copyPreferences(actionRequest, layout, copyLayout);

        SitesUtil.copyLookAndFeel(layout, copyLayout);
      }
    }

    updateLookAndFeel(
        actionRequest,
        themeDisplay.getCompanyId(),
        liveGroupId,
        stagingGroupId,
        privateLayout,
        layout.getLayoutId(),
        layout.getTypeSettingsProperties());
  }
  public void editLayout(ActionRequest actionRequest, ActionResponse actionResponse)
      throws Exception {

    UploadPortletRequest uploadPortletRequest = PortalUtil.getUploadPortletRequest(actionRequest);

    ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);

    long groupId = ParamUtil.getLong(actionRequest, "groupId");
    long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
    long stagingGroupId = ParamUtil.getLong(actionRequest, "stagingGroupId");
    boolean privateLayout = ParamUtil.getBoolean(actionRequest, "privateLayout");
    long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
    Map<Locale, String> nameMap = LocalizationUtil.getLocalizationMap(actionRequest, "name");
    Map<Locale, String> titleMap = LocalizationUtil.getLocalizationMap(actionRequest, "title");
    Map<Locale, String> descriptionMap =
        LocalizationUtil.getLocalizationMap(actionRequest, "description");
    Map<Locale, String> keywordsMap =
        LocalizationUtil.getLocalizationMap(actionRequest, "keywords");
    Map<Locale, String> robotsMap = LocalizationUtil.getLocalizationMap(actionRequest, "robots");
    String type = ParamUtil.getString(uploadPortletRequest, "type");
    boolean hidden = ParamUtil.getBoolean(uploadPortletRequest, "hidden");
    Map<Locale, String> friendlyURLMap =
        LocalizationUtil.getLocalizationMap(actionRequest, "friendlyURL");
    boolean deleteLogo = ParamUtil.getBoolean(actionRequest, "deleteLogo");

    byte[] iconBytes = null;

    long fileEntryId = ParamUtil.getLong(uploadPortletRequest, "fileEntryId");

    if (fileEntryId > 0) {
      FileEntry fileEntry = dlAppLocalService.getFileEntry(fileEntryId);

      iconBytes = FileUtil.getBytes(fileEntry.getContentStream());
    }

    ServiceContext serviceContext =
        ServiceContextFactory.getInstance(Layout.class.getName(), actionRequest);

    Layout layout = layoutLocalService.getLayout(groupId, privateLayout, layoutId);

    layout =
        layoutService.updateLayout(
            groupId,
            privateLayout,
            layoutId,
            layout.getParentLayoutId(),
            nameMap,
            titleMap,
            descriptionMap,
            keywordsMap,
            robotsMap,
            type,
            hidden,
            friendlyURLMap,
            !deleteLogo,
            iconBytes,
            serviceContext);

    UnicodeProperties layoutTypeSettingsProperties = layout.getTypeSettingsProperties();

    UnicodeProperties formTypeSettingsProperties =
        PropertiesParamUtil.getProperties(actionRequest, "TypeSettingsProperties--");

    LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

    if (type.equals(LayoutConstants.TYPE_PORTLET)) {
      String layoutTemplateId =
          ParamUtil.getString(
              uploadPortletRequest, "layoutTemplateId", PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID);

      layoutTypePortlet.setLayoutTemplateId(themeDisplay.getUserId(), layoutTemplateId);

      layoutTypeSettingsProperties.putAll(formTypeSettingsProperties);

      layoutService.updateLayout(
          groupId, privateLayout, layoutId, layoutTypeSettingsProperties.toString());
    } else {
      layout.setTypeSettingsProperties(formTypeSettingsProperties);

      layoutTypeSettingsProperties.putAll(layout.getTypeSettingsProperties());

      layoutService.updateLayout(groupId, privateLayout, layoutId, layout.getTypeSettings());
    }

    HttpServletResponse response = PortalUtil.getHttpServletResponse(actionResponse);

    EventsProcessorUtil.process(
        PropsKeys.LAYOUT_CONFIGURATION_ACTION_UPDATE,
        layoutTypePortlet.getConfigurationActionUpdate(),
        uploadPortletRequest,
        response);

    updateLookAndFeel(
        actionRequest,
        themeDisplay.getCompanyId(),
        liveGroupId,
        stagingGroupId,
        privateLayout,
        layout.getLayoutId(),
        layoutTypeSettingsProperties);
  }
  protected void getLayoutPortlets(
      PortletDataContext portletDataContext,
      long[] layoutIds,
      Map<String, Object[]> portletIds,
      Layout layout)
      throws Exception {

    if (!ArrayUtil.contains(layoutIds, layout.getLayoutId())) {
      return;
    }

    if (!prepareLayoutStagingHandler(portletDataContext, layout)
        || !layout.isSupportsEmbeddedPortlets()) {

      // Only portlet type layouts support page scoping

      return;
    }

    LayoutTypePortlet layoutTypePortlet = (LayoutTypePortlet) layout.getLayoutType();

    // The getAllPortlets method returns all effective nonsystem portlets
    // for any layout type, including embedded portlets, or in the case of
    // panel type layout, selected portlets

    for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
      String portletId = portlet.getPortletId();

      Settings portletInstanceSettings =
          SettingsFactoryUtil.getSettings(new PortletInstanceSettingsLocator(layout, portletId));

      String scopeType = portletInstanceSettings.getValue("lfrScopeType", null);
      String scopeLayoutUuid = portletInstanceSettings.getValue("lfrScopeLayoutUuid", null);

      long scopeGroupId = portletDataContext.getScopeGroupId();

      if (Validator.isNotNull(scopeType)) {
        Group scopeGroup = null;

        if (scopeType.equals("company")) {
          scopeGroup = _groupLocalService.getCompanyGroup(layout.getCompanyId());
        } else if (scopeType.equals("layout")) {
          Layout scopeLayout = null;

          scopeLayout =
              _layoutLocalService.fetchLayoutByUuidAndGroupId(
                  scopeLayoutUuid,
                  portletDataContext.getGroupId(),
                  portletDataContext.isPrivateLayout());

          if (scopeLayout == null) {
            continue;
          }

          scopeGroup = scopeLayout.getScopeGroup();
        } else {
          throw new IllegalArgumentException("Scope type " + scopeType + " is invalid");
        }

        if (scopeGroup != null) {
          scopeGroupId = scopeGroup.getGroupId();
        }
      }

      String key = PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portletId);

      portletIds.put(
          key,
          new Object[] {portletId, layout.getPlid(), scopeGroupId, scopeType, scopeLayoutUuid});
    }
  }