@Override
  protected Map<String, List<StagedModel>> addDependentStagedModelsMap(Group group)
      throws Exception {

    Map<String, List<StagedModel>> dependentStagedModelsMap = new LinkedHashMap<>();

    DDMStructure ddmStructure =
        DDMStructureTestUtil.addStructure(group.getGroupId(), DDLRecordSet.class.getName());

    DDMTemplate ddmTemplate1 =
        DDMTemplateTestUtil.addTemplate(
            group.getGroupId(),
            ddmStructure.getStructureId(),
            PortalUtil.getClassNameId(DDLRecordSet.class));

    addDependentStagedModel(dependentStagedModelsMap, DDMTemplate.class, ddmTemplate1);

    DDMTemplate ddmTemplate2 =
        DDMTemplateTestUtil.addTemplate(
            group.getGroupId(),
            ddmStructure.getStructureId(),
            PortalUtil.getClassNameId(DDLRecordSet.class));

    addDependentStagedModel(dependentStagedModelsMap, DDMTemplate.class, ddmTemplate2);

    addDependentStagedModel(dependentStagedModelsMap, DDMStructure.class, ddmStructure);

    return dependentStagedModelsMap;
  }
  private static LayoutSet _getParentLayoutSet(LayoutSet layoutSet) throws Exception {

    Group group = layoutSet.getGroup();

    if (group.isSite()) {
      Group parentGroup = group.getParentGroup();

      if (parentGroup != null) {
        return LayoutSetLocalServiceUtil.getLayoutSet(
            parentGroup.getGroupId(), layoutSet.isPrivateLayout());
      }
    } else if (group.isUser()) {
      User user = UserLocalServiceUtil.getUser(group.getClassPK());

      List<Organization> organizations =
          OrganizationLocalServiceUtil.getUserOrganizations(user.getUserId());

      if (!organizations.isEmpty()) {
        Organization organization = organizations.get(0);

        Group parentGroup = organization.getGroup();

        return LayoutSetLocalServiceUtil.getLayoutSet(
            parentGroup.getGroupId(), layoutSet.isPrivateLayout());
      }
    }

    return null;
  }
  @Override
  protected void validateImport(
      Map<String, List<StagedModel>> dependentStagedModelsMap, Group group) throws Exception {

    List<StagedModel> ddmStructureDependentStagedModels =
        dependentStagedModelsMap.get(DDMStructure.class.getSimpleName());

    Assert.assertEquals(1, ddmStructureDependentStagedModels.size());

    DDMStructure ddmStructure = (DDMStructure) ddmStructureDependentStagedModels.get(0);

    DDMStructureLocalServiceUtil.getDDMStructureByUuidAndGroupId(
        ddmStructure.getUuid(), group.getGroupId());

    List<StagedModel> ddmTemplateDependentStagedModels =
        dependentStagedModelsMap.get(DDMTemplate.class.getSimpleName());

    Assert.assertEquals(2, ddmTemplateDependentStagedModels.size());

    for (StagedModel ddmTemplateDependentStagedModel : ddmTemplateDependentStagedModels) {

      DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
          ddmTemplateDependentStagedModel.getUuid(), group.getGroupId());
    }
  }
  protected File[] exportLayouts(long userGroupId, Map<String, String[]> parameterMap)
      throws PortalException {

    File[] files = new File[2];

    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(userGroupId);

    User user = userLocalService.getUser(GetterUtil.getLong(PrincipalThreadLocal.getName()));

    Group group = userGroup.getGroup();

    if (userGroup.hasPrivateLayouts()) {
      Map<String, Serializable> exportLayoutSettingsMap =
          ExportImportConfigurationSettingsMapFactory.buildExportLayoutSettingsMap(
              user,
              group.getGroupId(),
              true,
              ExportImportHelperUtil.getAllLayoutIds(group.getGroupId(), true),
              parameterMap);

      ExportImportConfiguration exportImportConfiguration =
          exportImportConfigurationLocalService.addDraftExportImportConfiguration(
              user.getUserId(),
              ExportImportConfigurationConstants.TYPE_EXPORT_LAYOUT,
              exportLayoutSettingsMap);

      files[0] = exportImportLocalService.exportLayoutsAsFile(exportImportConfiguration);
    }

    if (userGroup.hasPublicLayouts()) {
      Map<String, Serializable> exportLayoutSettingsMap =
          ExportImportConfigurationSettingsMapFactory.buildExportLayoutSettingsMap(
              user,
              group.getGroupId(),
              false,
              ExportImportHelperUtil.getAllLayoutIds(group.getGroupId(), false),
              parameterMap);

      ExportImportConfiguration exportImportConfiguration =
          exportImportConfigurationLocalService.addDraftExportImportConfiguration(
              user.getUserId(),
              ExportImportConfigurationConstants.TYPE_EXPORT_LAYOUT,
              exportLayoutSettingsMap);

      files[1] = exportImportLocalService.exportLayoutsAsFile(exportImportConfiguration);
    }

    return files;
  }
  public void initPermissions(List<Company> companies, Portlet portlet) {
    String rootPortletId = portlet.getRootPortletId();

    for (Company company : companies) {
      long companyId = company.getCompanyId();

      Role powerUserRole = getPowerUserRole(companyId);

      if (powerUserRole == null) {
        continue;
      }

      Group userPersonalSiteGroup = getUserPersonalSiteGroup(companyId);

      if (userPersonalSiteGroup == null) {
        continue;
      }

      try {
        initPermissions(
            companyId,
            powerUserRole.getRoleId(),
            rootPortletId,
            userPersonalSiteGroup.getGroupId());
      } catch (PortalException pe) {
        _log.error(
            "Unable to initialize user personal site permissions "
                + "for portlet "
                + portlet.getPortletId()
                + " in company "
                + companyId,
            pe);
      }
    }
  }
  public void initPermissions(long companyId, List<Portlet> portlets) {
    Role powerUserRole = getPowerUserRole(companyId);

    if (powerUserRole == null) {
      return;
    }

    Group userPersonalSiteGroup = getUserPersonalSiteGroup(companyId);

    if (userPersonalSiteGroup == null) {
      return;
    }

    for (Portlet portlet : portlets) {
      try {
        initPermissions(
            companyId,
            powerUserRole.getRoleId(),
            portlet.getRootPortletId(),
            userPersonalSiteGroup.getGroupId());
      } catch (PortalException pe) {
        _log.error(
            "Unable to initialize user personal site permissions "
                + "for portlet "
                + portlet.getPortletId()
                + " in company "
                + companyId,
            pe);
      }
    }
  }
  protected String addBasicWebContentStructureAndTemplate(long companyId) throws Exception {

    initJournalDDMCompositeModelsResourceActions();

    Group group = _groupLocalService.getCompanyGroup(companyId);

    long defaultUserId = _userLocalService.getDefaultUserId(companyId);

    Class<?> clazz = getClass();

    _defaultDDMStructureHelper.addDDMStructures(
        defaultUserId,
        group.getGroupId(),
        PortalUtil.getClassNameId(JournalArticle.class),
        clazz.getClassLoader(),
        "com/liferay/journal/internal/upgrade/v1_0_0/dependencies"
            + "/basic-web-content-structure.xml",
        new ServiceContext());

    String defaultLanguageId = UpgradeProcessUtil.getDefaultLanguageId(companyId);

    Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);

    List<Element> structureElements = getDDMStructures(defaultLocale);

    Element structureElement = structureElements.get(0);

    return StringUtil.toUpperCase(structureElement.elementText("name"));
  }
  public static BreadcrumbEntry getGuestGroupBreadcrumbEntry(ThemeDisplay themeDisplay)
      throws Exception {

    Group group = GroupLocalServiceUtil.getGroup(themeDisplay.getCompanyId(), GroupConstants.GUEST);

    if (group.getPublicLayoutsPageCount() == 0) {
      return null;
    }

    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(group.getGroupId(), false);

    BreadcrumbEntry breadcrumbEntry = new BreadcrumbEntry();

    Account account = themeDisplay.getAccount();

    breadcrumbEntry.setTitle(account.getName());

    String layoutSetFriendlyURL = PortalUtil.getLayoutSetFriendlyURL(layoutSet, themeDisplay);

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

    breadcrumbEntry.setURL(layoutSetFriendlyURL);

    return breadcrumbEntry;
  }
  @Override
  protected void doDispatch(RenderRequest renderRequest, RenderResponse renderResponse)
      throws IOException, PortletException {

    try {
      User user = PortalUtil.getUser(renderRequest);

      RenderRequestImpl renderRequestImpl = (RenderRequestImpl) renderRequest;

      DynamicServletRequest dynamicRequest =
          (DynamicServletRequest) renderRequestImpl.getHttpServletRequest();

      dynamicRequest.setParameter("p_u_i_d", String.valueOf(user.getUserId()));

      Group group = user.getGroup();

      dynamicRequest.setParameter("groupId", String.valueOf(group.getGroupId()));

      ActionUtil.getGroup(renderRequest);
    } catch (Exception e) {
      throw new PortletException(e);
    }

    super.doDispatch(renderRequest, renderResponse);
  }
  protected String getGroupURL(
      Group group, PortletRequest portletRequest, boolean includeStagingGroup) {

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

    String groupDisplayURL = group.getDisplayURL(themeDisplay, false);

    if (Validator.isNotNull(groupDisplayURL)) {
      return HttpUtil.removeParameter(groupDisplayURL, "p_p_id");
    }

    groupDisplayURL = group.getDisplayURL(themeDisplay, true);

    if (Validator.isNotNull(groupDisplayURL)) {
      return HttpUtil.removeParameter(groupDisplayURL, "p_p_id");
    }

    if (includeStagingGroup && group.hasStagingGroup()) {
      try {
        if (GroupPermissionUtil.contains(
            themeDisplay.getPermissionChecker(), group, ActionKeys.VIEW_STAGING)) {

          return getGroupURL(group.getStagingGroup(), portletRequest);
        }
      } catch (PortalException pe) {
        _log.error("Unable to check permission on group " + group.getGroupId(), pe);
      }
    }

    return getGroupAdministrationURL(group, portletRequest);
  }
 @Override
 protected StagedModel getStagedModel(String uuid, Group group) {
   try {
     return DDLRecordSetLocalServiceUtil.getDDLRecordSetByUuidAndGroupId(uuid, group.getGroupId());
   } catch (Exception e) {
     return null;
   }
 }
 @Override
 protected StagedModel getStagedModel(String uuid, Group group) {
   try {
     return LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(uuid, group.getGroupId(), false);
   } catch (Exception e) {
     return null;
   }
 }
  @Override
  protected Map<String, List<StagedModel>> addDependentStagedModelsMap(Group group)
      throws Exception {

    Map<String, List<StagedModel>> dependentStagedModelsMap = new HashMap<>();

    AssetVocabulary vocabulary = AssetTestUtil.addVocabulary(group.getGroupId());

    addDependentStagedModel(dependentStagedModelsMap, AssetVocabulary.class, vocabulary);

    AssetCategory category =
        AssetTestUtil.addCategory(group.getGroupId(), vocabulary.getVocabularyId());

    addDependentStagedModel(dependentStagedModelsMap, AssetCategory.class, category);

    return dependentStagedModelsMap;
  }
  @Override
  public void onAfterAddAssociation(
      Object classPK, String associationClassName, Object associationClassPK)
      throws ModelListenerException {

    try {
      User user = userLocalService.getUser((Long) classPK);

      if (associationClassName.equals(Group.class.getName())
          || associationClassName.equals(Organization.class.getName())
          || associationClassName.equals(UserGroup.class.getName())) {

        Role role =
            roleLocalService.fetchRole(user.getCompanyId(), RoleConstants.SOCIAL_OFFICE_USER);

        if (role == null) {
          return;
        }

        Group group = null;

        if (associationClassName.equals(Group.class.getName())) {
          group = groupLocalService.getGroup((Long) associationClassPK);
        } else if (associationClassName.equals(Organization.class.getName())) {

          group =
              groupLocalService.getOrganizationGroup(
                  user.getCompanyId(), (Long) associationClassPK);
        } else if (associationClassName.equals(UserGroup.class.getName())) {

          group =
              groupLocalService.getUserGroupGroup(user.getCompanyId(), (Long) associationClassPK);
        }

        if (groupLocalService.hasRoleGroup(role.getRoleId(), group.getGroupId())) {

          enableSocialOffice(user.getGroup());
        }
      } else if (associationClassName.equals(Role.class.getName())) {
        Role role = roleLocalService.getRole((Long) associationClassPK);

        String name = role.getName();

        if (name.equals(RoleConstants.SOCIAL_OFFICE_USER)) {
          enableSocialOffice(user.getGroup());
        }
      }
    } catch (NoSuchGroupException nsge) {

      // LPS-52675

      if (_log.isDebugEnabled()) {
        _log.debug(nsge, nsge);
      }
    } catch (Exception e) {
      throw new ModelListenerException(e);
    }
  }
  @Override
  public String replaceExportContentReferences(
      PortletDataContext portletDataContext,
      StagedModel stagedModel,
      String content,
      boolean exportReferencedContent,
      boolean escapeContent)
      throws Exception {

    JournalFeed feed = (JournalFeed) stagedModel;

    Group group = _groupLocalService.getGroup(portletDataContext.getScopeGroupId());

    String newGroupFriendlyURL = group.getFriendlyURL();

    newGroupFriendlyURL = newGroupFriendlyURL.substring(1);

    String[] friendlyURLParts =
        StringUtil.split(feed.getTargetLayoutFriendlyUrl(), StringPool.FORWARD_SLASH);

    String oldGroupFriendlyURL = friendlyURLParts[2];

    if (newGroupFriendlyURL.equals(oldGroupFriendlyURL)) {
      String targetLayoutFriendlyUrl =
          StringUtil.replaceFirst(
              feed.getTargetLayoutFriendlyUrl(),
              StringPool.SLASH + newGroupFriendlyURL + StringPool.SLASH,
              StringPool.SLASH + DATA_HANDLER_GROUP_FRIENDLY_URL + StringPool.SLASH);

      feed.setTargetLayoutFriendlyUrl(targetLayoutFriendlyUrl);
    }

    Group targetLayoutGroup =
        _groupLocalService.fetchFriendlyURLGroup(
            portletDataContext.getCompanyId(), StringPool.SLASH + oldGroupFriendlyURL);

    boolean privateLayout = false;

    if (!PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING.equals(
        StringPool.SLASH + friendlyURLParts[1])) {

      privateLayout = true;
    }

    String targetLayoutFriendlyURL = StringPool.SLASH + friendlyURLParts[3];

    Layout targetLayout =
        _layoutLocalService.fetchLayoutByFriendlyURL(
            targetLayoutGroup.getGroupId(), privateLayout, targetLayoutFriendlyURL);

    Element feedElement = portletDataContext.getExportDataElement(feed);

    portletDataContext.addReferenceElement(
        feed, feedElement, targetLayout, PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);

    return content;
  }
 @Override
 protected StagedModel getStagedModel(String uuid, Group group) {
   try {
     return AssetCategoryLocalServiceUtil.getAssetCategoryByUuidAndGroupId(
         uuid, group.getGroupId());
   } catch (Exception e) {
     return null;
   }
 }
  protected void enableSocialOffice(Group group) throws Exception {
    if (socialOfficeUtil.isSocialOfficeGroup(group.getGroupId())) {
      return;
    }

    layoutSetPrototypeUtil.updateLayoutSetPrototype(
        group, false, SocialOfficeConstants.LAYOUT_SET_PROTOTYPE_KEY_USER_PUBLIC);
    layoutSetPrototypeUtil.updateLayoutSetPrototype(
        group, true, SocialOfficeConstants.LAYOUT_SET_PROTOTYPE_KEY_USER_PRIVATE);

    socialOfficeUtil.enableSocialOffice(group);
  }
  @Override
  protected void validateImport(
      Map<String, List<StagedModel>> dependentStagedModelsMap, Group group) throws Exception {

    List<StagedModel> dependentStagedModels =
        dependentStagedModelsMap.get(Layout.class.getSimpleName());

    Assert.assertEquals(1, dependentStagedModels.size());

    Layout parentLayout = (Layout) dependentStagedModels.get(0);

    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
        parentLayout.getUuid(), group.getGroupId(), false);

    List<LayoutFriendlyURL> parentLayoutFriendlyURLs =
        LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLs(parentLayout.getPlid());

    LayoutFriendlyURL parentLayoutFriendlyURL = parentLayoutFriendlyURLs.get(0);

    LayoutFriendlyURLLocalServiceUtil.getLayoutFriendlyURLByUuidAndGroupId(
        parentLayoutFriendlyURL.getUuid(), group.getGroupId());
  }
  @Override
  protected void validateImport(
      Map<String, List<StagedModel>> dependentStagedModelsMap, Group group) throws Exception {

    List<StagedModel> categoryDependentStagedModels =
        dependentStagedModelsMap.get(AssetCategory.class.getSimpleName());

    Assert.assertEquals(1, categoryDependentStagedModels.size());

    AssetCategory category = (AssetCategory) categoryDependentStagedModels.get(0);

    AssetCategoryLocalServiceUtil.getAssetCategoryByUuidAndGroupId(
        category.getUuid(), group.getGroupId());

    List<StagedModel> vocabularyDependentStagedModels =
        dependentStagedModelsMap.get(AssetVocabulary.class.getSimpleName());

    Assert.assertEquals(1, vocabularyDependentStagedModels.size());

    AssetVocabulary vocabulary = (AssetVocabulary) vocabularyDependentStagedModels.get(0);

    AssetVocabularyLocalServiceUtil.getAssetVocabularyByUuidAndGroupId(
        vocabulary.getUuid(), group.getGroupId());
  }
  @Override
  protected StagedModel addStagedModel(
      Group group, Map<String, List<StagedModel>> dependentStagedModelsMap) throws Exception {

    List<StagedModel> vocabularyDependentStagedModels =
        dependentStagedModelsMap.get(AssetVocabulary.class.getSimpleName());

    AssetVocabulary vocabulary = (AssetVocabulary) vocabularyDependentStagedModels.get(0);

    List<StagedModel> categoryDependentStagedModels =
        dependentStagedModelsMap.get(AssetCategory.class.getSimpleName());

    AssetCategory category = (AssetCategory) categoryDependentStagedModels.get(0);

    return AssetTestUtil.addCategory(
        group.getGroupId(), vocabulary.getVocabularyId(), category.getCategoryId());
  }
  public User addUser(Group group, String... assetTagNames) throws Exception {
    User user1 = UserTestUtil.addUser(group.getGroupId());

    _users.add(user1);

    ServiceContext serviceContext = getServiceContext(group);

    serviceContext.setAssetTagNames(assetTagNames);

    User user2 = UserTestUtil.updateUser(user1, serviceContext);

    List<AssetTag> assetTags =
        AssetTagLocalServiceUtil.getTags(user2.getModelClassName(), user2.getPrimaryKey());

    _assetTags.addAll(assetTags);

    return user2;
  }
  protected long getParentGroupId(PortletRequest portletRequest) {
    Group group = null;

    long groupId =
        ParamUtil.getLong(portletRequest, "groupId", GroupConstants.DEFAULT_PARENT_GROUP_ID);

    if (groupId > 0) {
      group = _groupLocalService.fetchGroup(groupId);
    }

    if (group != null) {
      return group.getGroupId();
    }

    if (isFilterManageableGroups(portletRequest)) {
      return GroupConstants.ANY_PARENT_GROUP_ID;
    }

    return GroupConstants.DEFAULT_PARENT_GROUP_ID;
  }
    @Override
    public Void call() throws PortalException {
      Group group = _groupLocalService.getGroup(_groupId);

      Date endDate = null;

      if (_dateRange != null) {
        endDate = _dateRange.getEndDate();
      }

      if (group.hasStagingGroup()) {
        Group stagingGroup = group.getStagingGroup();

        ExportImportDateUtil.updateLastPublishDate(
            stagingGroup.getGroupId(), _privateLayout, _dateRange, endDate);
      } else {
        ExportImportDateUtil.updateLastPublishDate(_groupId, _privateLayout, _dateRange, endDate);
      }

      return null;
    }
  protected void updateRobots(ActionRequest actionRequest, long liveGroupId, boolean privateLayout)
      throws Exception {

    Group liveGroup = groupLocalService.getGroup(liveGroupId);

    UnicodeProperties typeSettingsProperties = liveGroup.getTypeSettingsProperties();

    String propertyName = "false-robots.txt";

    if (privateLayout) {
      propertyName = "true-robots.txt";
    }

    String robots =
        ParamUtil.getString(
            actionRequest, "robots", liveGroup.getTypeSettingsProperty(propertyName));

    typeSettingsProperties.setProperty(propertyName, robots);

    groupService.updateGroup(liveGroup.getGroupId(), typeSettingsProperties.toString());
  }
  @Override
  public void validate(
      long groupId, String className, long classTypePK, long[] categoryIds, String[] entryNames)
      throws PortalException {

    if (className.equals(DLFileEntryConstants.getClassName())) {
      DLFileEntry dlFileEntry = _dlFileEntryLocalService.fetchDLFileEntry(classTypePK);

      if ((dlFileEntry == null) || (dlFileEntry.getRepositoryId() != groupId)) {

        return;
      }
    }

    List<AssetVocabulary> assetVocabularies =
        _assetVocabularyLocalService.getGroupVocabularies(groupId, false);

    Group group = _groupLocalService.getGroup(groupId);

    if (!group.isCompany()) {
      Group companyGroup = _groupLocalService.fetchCompanyGroup(group.getCompanyId());

      if (companyGroup != null) {
        assetVocabularies = ListUtil.copy(assetVocabularies);

        assetVocabularies.addAll(
            _assetVocabularyLocalService.getGroupVocabularies(companyGroup.getGroupId()));
      }
    }

    long classNameId = _classNameLocalService.getClassNameId(className);

    if (isCategorizable(classNameId)) {
      for (AssetVocabulary assetVocabulary : assetVocabularies) {
        validate(classNameId, classTypePK, categoryIds, assetVocabulary);
      }
    }
  }
  /**
   * Returns an export layout settings map if the type is {@link
   * ExportImportConfigurationConstants#TYPE_EXPORT_LAYOUT}; otherwise, returns either a local or
   * remote publish layout settings map, depending on the staging type.
   *
   * @param portletRequest the portlet request
   * @param groupId the primary key of the group
   * @param type the export/import option type
   * @return an export layout settings map if the type is an export layout; otherwise, returns
   *     either a local or remote publish layout settings map, depending on the staging type
   */
  public static Map<String, Serializable> buildSettingsMap(
      PortletRequest portletRequest, long groupId, int type) throws PortalException {

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

    boolean privateLayout = ParamUtil.getBoolean(portletRequest, "privateLayout");

    Map<Long, Boolean> layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);

    if (type == ExportImportConfigurationConstants.TYPE_EXPORT_LAYOUT) {
      long[] layoutIds = ExportImportHelperUtil.getLayoutIds(layoutIdMap);

      return buildExportLayoutSettingsMap(
          themeDisplay.getUserId(),
          groupId,
          privateLayout,
          layoutIds,
          portletRequest.getParameterMap(),
          themeDisplay.getLocale(),
          themeDisplay.getTimeZone());
    }

    Group stagingGroup = GroupLocalServiceUtil.getGroup(groupId);

    Group liveGroup = stagingGroup.getLiveGroup();

    Map<String, String[]> parameterMap =
        ExportImportConfigurationParameterMapFactory.buildParameterMap(portletRequest);

    if (liveGroup != null) {
      long[] layoutIds = ExportImportHelperUtil.getLayoutIds(layoutIdMap, liveGroup.getGroupId());

      return buildPublishLayoutLocalSettingsMap(
          themeDisplay.getUserId(),
          stagingGroup.getGroupId(),
          liveGroup.getGroupId(),
          privateLayout,
          layoutIds,
          parameterMap,
          themeDisplay.getLocale(),
          themeDisplay.getTimeZone());
    }

    UnicodeProperties groupTypeSettingsProperties = stagingGroup.getTypeSettingsProperties();

    String remoteAddress =
        ParamUtil.getString(
            portletRequest,
            "remoteAddress",
            groupTypeSettingsProperties.getProperty("remoteAddress"));

    remoteAddress = StagingUtil.stripProtocolFromRemoteAddress(remoteAddress);

    int remotePort =
        ParamUtil.getInteger(
            portletRequest,
            "remotePort",
            GetterUtil.getInteger(groupTypeSettingsProperties.getProperty("remotePort")));
    String remotePathContext =
        ParamUtil.getString(
            portletRequest,
            "remotePathContext",
            groupTypeSettingsProperties.getProperty("remotePathContext"));
    boolean secureConnection =
        ParamUtil.getBoolean(
            portletRequest,
            "secureConnection",
            GetterUtil.getBoolean(groupTypeSettingsProperties.getProperty("secureConnection")));
    long remoteGroupId =
        ParamUtil.getLong(
            portletRequest,
            "remoteGroupId",
            GetterUtil.getLong(groupTypeSettingsProperties.getProperty("remoteGroupId")));
    boolean remotePrivateLayout = ParamUtil.getBoolean(portletRequest, "remotePrivateLayout");

    StagingUtil.validateRemote(
        groupId, remoteAddress, remotePort, remotePathContext, secureConnection, remoteGroupId);

    return buildPublishLayoutRemoteSettingsMap(
        themeDisplay.getUserId(),
        groupId,
        privateLayout,
        layoutIdMap,
        parameterMap,
        remoteAddress,
        remotePort,
        remotePathContext,
        secureConnection,
        remoteGroupId,
        remotePrivateLayout,
        themeDisplay.getLocale(),
        themeDisplay.getTimeZone());
  }
  protected File doExport(PortletDataContext portletDataContext, long[] layoutIds)
      throws Exception {

    Map<String, String[]> parameterMap = portletDataContext.getParameterMap();

    boolean ignoreLastPublishDate =
        MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE);
    boolean layoutSetPrototypeSettings =
        MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_SETTINGS);
    boolean layoutSetSettings =
        MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
    boolean logo = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.LOGO);
    boolean permissions = MapUtil.getBoolean(parameterMap, PortletDataHandlerKeys.PERMISSIONS);

    if (_log.isDebugEnabled()) {
      _log.debug("Export permissions " + permissions);
    }

    LayoutSet layoutSet =
        _layoutSetLocalService.getLayoutSet(
            portletDataContext.getGroupId(), portletDataContext.isPrivateLayout());

    long companyId = layoutSet.getCompanyId();
    long defaultUserId = _userLocalService.getDefaultUserId(companyId);

    ServiceContext serviceContext = ServiceContextThreadLocal.popServiceContext();

    if (serviceContext == null) {
      serviceContext = new ServiceContext();
    }

    serviceContext.setCompanyId(companyId);
    serviceContext.setSignedIn(false);
    serviceContext.setUserId(defaultUserId);

    serviceContext.setAttribute("exporting", Boolean.TRUE);

    long layoutSetBranchId = MapUtil.getLong(parameterMap, "layoutSetBranchId");

    serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId);

    ServiceContextThreadLocal.pushServiceContext(serviceContext);

    if (ignoreLastPublishDate) {
      portletDataContext.setEndDate(null);
      portletDataContext.setStartDate(null);
    }

    StopWatch stopWatch = new StopWatch();

    stopWatch.start();

    Document document = SAXReaderUtil.createDocument();

    Element rootElement = document.addElement("root");

    portletDataContext.setExportDataRootElement(rootElement);

    Element headerElement = rootElement.addElement("header");

    headerElement.addAttribute(
        "available-locales",
        StringUtil.merge(LanguageUtil.getAvailableLocales(portletDataContext.getScopeGroupId())));
    headerElement.addAttribute("build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
    headerElement.addAttribute("export-date", Time.getRFC822());

    if (portletDataContext.hasDateRange()) {
      headerElement.addAttribute("start-date", String.valueOf(portletDataContext.getStartDate()));
      headerElement.addAttribute("end-date", String.valueOf(portletDataContext.getEndDate()));
    }

    headerElement.addAttribute("company-id", String.valueOf(portletDataContext.getCompanyId()));
    headerElement.addAttribute(
        "company-group-id", String.valueOf(portletDataContext.getCompanyGroupId()));
    headerElement.addAttribute("group-id", String.valueOf(portletDataContext.getGroupId()));
    headerElement.addAttribute(
        "user-personal-site-group-id",
        String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
    headerElement.addAttribute(
        "private-layout", String.valueOf(portletDataContext.isPrivateLayout()));

    Group group = layoutSet.getGroup();

    String type = "layout-set";

    if (group.isLayoutPrototype()) {
      type = "layout-prototype";

      LayoutPrototype layoutPrototype =
          _layoutPrototypeLocalService.getLayoutPrototype(group.getClassPK());

      headerElement.addAttribute("type-uuid", layoutPrototype.getUuid());

      layoutIds =
          ExportImportHelperUtil.getAllLayoutIds(
              portletDataContext.getGroupId(), portletDataContext.isPrivateLayout());
    } else if (group.isLayoutSetPrototype()) {
      type = "layout-set-prototype";

      LayoutSetPrototype layoutSetPrototype =
          _layoutSetPrototypeLocalService.getLayoutSetPrototype(group.getClassPK());

      headerElement.addAttribute("type-uuid", layoutSetPrototype.getUuid());
    }

    headerElement.addAttribute("type", type);

    LayoutSetBranch layoutSetBranch =
        _layoutSetBranchLocalService.fetchLayoutSetBranch(layoutSetBranchId);

    if (logo) {
      Image image = null;

      if (layoutSetBranch != null) {
        image = _imageLocalService.getImage(layoutSetBranch.getLogoId());
      } else {
        image = _imageLocalService.getImage(layoutSet.getLogoId());
      }

      if ((image != null) && (image.getTextObj() != null)) {
        String logoPath = ExportImportPathUtil.getRootPath(portletDataContext);

        logoPath += "/logo";

        headerElement.addAttribute("logo-path", logoPath);

        portletDataContext.addZipEntry(logoPath, image.getTextObj());
      }
    }

    String layoutSetPrototypeUuid = layoutSet.getLayoutSetPrototypeUuid();

    if (layoutSetPrototypeSettings && Validator.isNotNull(layoutSetPrototypeUuid)) {

      LayoutSetPrototype layoutSetPrototype =
          _layoutSetPrototypeLocalService.getLayoutSetPrototypeByUuidAndCompanyId(
              layoutSetPrototypeUuid, companyId);

      headerElement.addAttribute("layout-set-prototype-uuid", layoutSetPrototypeUuid);
      headerElement.addAttribute(
          "layout-set-prototype-name", layoutSetPrototype.getName(LocaleUtil.getDefault()));
    }

    Element missingReferencesElement = rootElement.addElement("missing-references");

    portletDataContext.setMissingReferencesElement(missingReferencesElement);

    if (layoutSetBranch != null) {
      _themeExporter.exportTheme(portletDataContext, layoutSetBranch);
    } else {
      _themeExporter.exportTheme(portletDataContext, layoutSet);
    }

    if (layoutSetSettings) {
      Element settingsElement = headerElement.addElement("settings");

      if (layoutSetBranch != null) {
        settingsElement.addCDATA(layoutSetBranch.getSettings());
      } else {
        settingsElement.addCDATA(layoutSet.getSettings());
      }
    }

    Map<String, Object[]> portletIds = new LinkedHashMap<>();

    List<Layout> layouts =
        _layoutLocalService.getLayouts(
            portletDataContext.getGroupId(), portletDataContext.isPrivateLayout());

    if (group.isStagingGroup()) {
      group = group.getLiveGroup();
    }

    // Collect data portlets

    for (Portlet portlet : ExportImportHelperUtil.getDataSiteLevelPortlets(companyId)) {

      String portletId = portlet.getRootPortletId();

      if (ExportImportThreadLocal.isStagingInProcess() && !group.isStagedPortlet(portletId)) {

        continue;
      }

      // Calculate the amount of exported data

      if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
        PortletDataHandler portletDataHandler = portlet.getPortletDataHandlerInstance();

        portletDataHandler.prepareManifestSummary(portletDataContext);
      }

      // Add portlet ID to exportable portlets list

      portletIds.put(
          PortletPermissionUtil.getPrimaryKey(0, portletId),
          new Object[] {
            portletId,
            LayoutConstants.DEFAULT_PLID,
            portletDataContext.getGroupId(),
            StringPool.BLANK,
            StringPool.BLANK
          });

      if (!portlet.isScopeable()) {
        continue;
      }

      // Scoped data

      for (Layout layout : layouts) {
        if (!ArrayUtil.contains(layoutIds, layout.getLayoutId())
            || !layout.isTypePortlet()
            || !layout.hasScopeGroup()) {

          continue;
        }

        Group scopeGroup = layout.getScopeGroup();

        portletIds.put(
            PortletPermissionUtil.getPrimaryKey(layout.getPlid(), portlet.getPortletId()),
            new Object[] {
              portlet.getPortletId(),
              layout.getPlid(),
              scopeGroup.getGroupId(),
              StringPool.BLANK,
              layout.getUuid()
            });
      }
    }

    // Collect layout portlets

    for (Layout layout : layouts) {
      getLayoutPortlets(portletDataContext, layoutIds, portletIds, layout);
    }

    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
      ManifestSummary manifestSummary = portletDataContext.getManifestSummary();

      PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
          "layout", ArrayUtil.toStringArray(portletIds.keySet()), manifestSummary);

      manifestSummary.resetCounters();
    }

    // Export actual data

    portletDataContext.addDeletionSystemEventStagedModelTypes(new StagedModelType(Layout.class));

    // Force to always have a layout group element

    portletDataContext.getExportDataGroupElement(Layout.class);

    for (Layout layout : layouts) {
      exportLayout(portletDataContext, layoutIds, layout);
    }

    Element portletsElement = rootElement.addElement("portlets");

    Element servicesElement = rootElement.addElement("services");

    long previousScopeGroupId = portletDataContext.getScopeGroupId();

    for (Map.Entry<String, Object[]> portletIdsEntry : portletIds.entrySet()) {

      Object[] portletObjects = portletIdsEntry.getValue();

      String portletId = null;
      long plid = LayoutConstants.DEFAULT_PLID;
      long scopeGroupId = 0;
      String scopeType = StringPool.BLANK;
      String scopeLayoutUuid = null;

      if (portletObjects.length == 4) {
        portletId = (String) portletIdsEntry.getValue()[0];
        plid = (Long) portletIdsEntry.getValue()[1];
        scopeGroupId = (Long) portletIdsEntry.getValue()[2];
        scopeLayoutUuid = (String) portletIdsEntry.getValue()[3];
      } else {
        portletId = (String) portletIdsEntry.getValue()[0];
        plid = (Long) portletIdsEntry.getValue()[1];
        scopeGroupId = (Long) portletIdsEntry.getValue()[2];
        scopeType = (String) portletIdsEntry.getValue()[3];
        scopeLayoutUuid = (String) portletIdsEntry.getValue()[4];
      }

      Layout layout = _layoutLocalService.fetchLayout(plid);

      if (layout == null) {
        layout = new LayoutImpl();

        layout.setCompanyId(companyId);
        layout.setGroupId(portletDataContext.getGroupId());
      }

      portletDataContext.setPlid(plid);
      portletDataContext.setOldPlid(plid);
      portletDataContext.setPortletId(portletId);
      portletDataContext.setScopeGroupId(scopeGroupId);
      portletDataContext.setScopeType(scopeType);
      portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);

      Map<String, Boolean> exportPortletControlsMap =
          ExportImportHelperUtil.getExportPortletControlsMap(
              companyId, portletId, parameterMap, type);

      try {
        _exportImportLifecycleManager.fireExportImportLifecycleEvent(
            EVENT_PORTLET_EXPORT_STARTED,
            getProcessFlag(),
            PortletDataContextFactoryUtil.clonePortletDataContext(portletDataContext));

        _portletExportController.exportPortlet(
            portletDataContext,
            layout,
            portletsElement,
            permissions,
            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_DATA),
            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP),
            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
        _portletExportController.exportService(
            portletDataContext,
            servicesElement,
            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP));

        _exportImportLifecycleManager.fireExportImportLifecycleEvent(
            EVENT_PORTLET_EXPORT_SUCCEEDED,
            getProcessFlag(),
            PortletDataContextFactoryUtil.clonePortletDataContext(portletDataContext));
      } catch (Throwable t) {
        _exportImportLifecycleManager.fireExportImportLifecycleEvent(
            EVENT_PORTLET_EXPORT_FAILED,
            getProcessFlag(),
            PortletDataContextFactoryUtil.clonePortletDataContext(portletDataContext),
            t);

        throw t;
      }
    }

    portletDataContext.setScopeGroupId(previousScopeGroupId);

    _portletExportController.exportAssetLinks(portletDataContext);
    _portletExportController.exportExpandoTables(portletDataContext);
    _portletExportController.exportLocks(portletDataContext);

    _deletionSystemEventExporter.exportDeletionSystemEvents(portletDataContext);

    if (permissions) {
      _permissionExporter.exportPortletDataPermissions(portletDataContext);
    }

    ExportImportHelperUtil.writeManifestSummary(document, portletDataContext.getManifestSummary());

    if (_log.isInfoEnabled()) {
      _log.info("Exporting layouts takes " + stopWatch.getTime() + " ms");
    }

    boolean updateLastPublishDate =
        MapUtil.getBoolean(
            portletDataContext.getParameterMap(), PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);

    if (ExportImportThreadLocal.isStagingInProcess() && updateLastPublishDate) {

      ExportImportProcessCallbackRegistryUtil.registerCallback(
          new UpdateLayoutSetLastPublishDateCallable(
              portletDataContext.getDateRange(),
              portletDataContext.getGroupId(),
              portletDataContext.isPrivateLayout()));
    }

    portletDataContext.addZipEntry("/manifest.xml", document.formattedString());

    ZipWriter zipWriter = portletDataContext.getZipWriter();

    return zipWriter.getFile();
  }
  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});
    }
  }
  protected static ServiceContext getServiceContext(Group group) throws Exception {

    return ServiceContextTestUtil.getServiceContext(
        group.getGroupId(), TestPropsValues.getUserId());
  }
  @Override
  public void onAfterRemoveAssociation(
      Object classPK, String associationClassName, Object associationClassPK)
      throws ModelListenerException {

    try {
      User user = userLocalService.getUser((Long) classPK);

      FinderCacheUtil.clearCache(_MAPPING_TABLE_USERS_ROLES_NAME_LEFT_TO_RIGHT);
      FinderCacheUtil.clearCache(_MAPPING_TABLE_USERS_ROLES_NAME_RIGHT_TO_LEFT);

      ThreadLocalCacheManager.clearAll(Lifecycle.REQUEST);

      if (userLocalService.hasRoleUser(
          user.getCompanyId(), RoleConstants.SOCIAL_OFFICE_USER, user.getUserId(), true)) {

        return;
      }

      if (associationClassName.equals(Group.class.getName())
          || associationClassName.equals(Organization.class.getName())
          || associationClassName.equals(UserGroup.class.getName())) {

        Role role = roleLocalService.getRole(user.getCompanyId(), RoleConstants.SOCIAL_OFFICE_USER);

        Group group = null;

        if (associationClassName.equals(Group.class.getName())) {
          group = groupLocalService.getGroup((Long) associationClassPK);
        } else if (associationClassName.equals(Organization.class.getName())) {

          group =
              groupLocalService.getOrganizationGroup(
                  user.getCompanyId(), (Long) associationClassPK);
        } else if (associationClassName.equals(UserGroup.class.getName())) {

          group =
              groupLocalService.getUserGroupGroup(user.getCompanyId(), (Long) associationClassPK);
        }

        if (groupLocalService.hasRoleGroup(role.getRoleId(), group.getGroupId())) {

          disableSocialOffice(user.getGroup());
        }
      } else if (associationClassName.equals(Role.class.getName())) {
        Role role = roleLocalService.getRole((Long) associationClassPK);

        String name = role.getName();

        if (name.equals(RoleConstants.SOCIAL_OFFICE_USER)) {
          disableSocialOffice(user.getGroup());
        }
      }
    } catch (NoSuchGroupException nsge) {

      // LPS-52675

      if (_log.isDebugEnabled()) {
        _log.debug(nsge, nsge);
      }
    } catch (Exception e) {
      throw new ModelListenerException(e);
    }
  }