public JSONArray getJSONActivityDefinitions(long groupId, String className)
      throws PortalException, SystemException {

    JSONArray jsonArray = JSONFactoryUtil.createJSONArray();

    List<SocialActivityDefinition> activityDefinitions =
        socialActivitySettingLocalService.getActivityDefinitions(groupId, className);

    for (SocialActivityDefinition activityDefinition : activityDefinitions) {

      JSONObject activityDefinitionJSONObject =
          JSONFactoryUtil.createJSONObject(JSONFactoryUtil.looseSerialize(activityDefinition));

      JSONArray activityCounterDefinitionsJSONArray = JSONFactoryUtil.createJSONArray();

      for (SocialActivityCounterDefinition activityCounterDefinition :
          activityDefinition.getActivityCounterDefinitions()) {

        JSONObject activityCounterDefinitionJSONObject =
            JSONFactoryUtil.createJSONObject(
                JSONFactoryUtil.looseSerialize(activityCounterDefinition));

        activityCounterDefinitionsJSONArray.put(activityCounterDefinitionJSONObject);
      }

      activityDefinitionJSONObject.put("counters", activityCounterDefinitionsJSONArray);

      jsonArray.put(activityDefinitionJSONObject);
    }

    return jsonArray;
  }
  protected Map<String, Boolean> getActivitySettingsMap(ThemeDisplay themeDisplay)
      throws Exception {

    Map<String, Boolean> activitySettingsMap = new LinkedHashMap<>();

    List<SocialActivitySetting> activitySettings =
        SocialActivitySettingServiceUtil.getActivitySettings(
            themeDisplay.getSiteGroupIdOrLiveGroupId());

    String[] modelNames = SocialConfigurationUtil.getActivityModelNames();

    Comparator<String> comparator = new ModelResourceComparator(themeDisplay.getLocale());

    Arrays.sort(modelNames, comparator);

    for (String modelName : modelNames) {
      List<SocialActivityDefinition> activityDefinitions =
          SocialActivitySettingServiceUtil.getActivityDefinitions(
              themeDisplay.getScopeGroupId(), modelName);

      for (SocialActivityDefinition activityDefinition : activityDefinitions) {

        if (activityDefinition.isCountersEnabled()) {
          activitySettingsMap.put(modelName, false);

          break;
        }
      }
    }

    for (SocialActivitySetting activitySetting : activitySettings) {
      String name = activitySetting.getName();

      if (name.equals("enabled")
          && activitySettingsMap.containsKey(activitySetting.getClassName())) {

        activitySettingsMap.put(
            activitySetting.getClassName(), GetterUtil.getBoolean(activitySetting.getValue()));
      }
    }

    return activitySettingsMap;
  }
  @Async
  public void addActivity(SocialActivity activity, SocialActivity mirrorActivity)
      throws PortalException, SystemException {

    if (ImportExportThreadLocal.isImportInProcess()) {
      return;
    }

    if ((activity.getActivityId() > 0)
        || ((mirrorActivity != null) && (mirrorActivity.getActivityId() > 0))) {

      throw new PortalException("Activity and mirror activity must not have primary keys set");
    }

    SocialActivityDefinition activityDefinition =
        socialActivitySettingLocalService.getActivityDefinition(
            activity.getGroupId(), activity.getClassName(), activity.getType());

    if ((activityDefinition == null) || activityDefinition.isLogActivity()) {

      long activityId = counterLocalService.increment(SocialActivity.class.getName());

      activity.setActivityId(activityId);

      socialActivityPersistence.update(activity, false);

      if (mirrorActivity != null) {
        long mirrorActivityId = counterLocalService.increment(SocialActivity.class.getName());

        mirrorActivity.setActivityId(mirrorActivityId);
        mirrorActivity.setMirrorActivityId(activity.getPrimaryKey());

        socialActivityPersistence.update(mirrorActivity, false);
      }
    }

    socialActivityCounterLocalService.addActivityCounters(activity);
  }
  protected boolean isLogActivity(SocialActivity activity) {
    if (activity.getType() == SocialActivityConstants.TYPE_DELETE) {
      if (activity.getParentClassPK() == 0) {
        return true;
      }

      return false;
    }

    SocialActivityDefinition activityDefinition =
        socialActivitySettingLocalService.getActivityDefinition(
            activity.getGroupId(), activity.getClassName(), activity.getType());

    if (activityDefinition != null) {
      return activityDefinition.isLogActivity();
    }

    if (activity.getType() < SocialActivityConstants.TYPE_VIEW) {
      return true;
    }

    return false;
  }
  protected SocialActivityCounterDefinition updateActivityCounterDefinition(
      JSONObject actionJSONObject,
      SocialActivityDefinition activityDefinition,
      String activityCounterName) {

    SocialActivityCounterDefinition activityCounterDefinition =
        activityDefinition.getActivityCounterDefinition(activityCounterName);

    if (activityCounterDefinition == null) {
      activityCounterDefinition = new SocialActivityCounterDefinition();

      activityCounterDefinition.setName(activityCounterName);
    }

    if (activityCounterName.equals(SocialActivityCounterConstants.NAME_CONTRIBUTION)) {

      activityCounterDefinition.setOwnerType(SocialActivityCounterConstants.TYPE_CREATOR);
    } else if (activityCounterName.equals(SocialActivityCounterConstants.NAME_PARTICIPATION)) {

      activityCounterDefinition.setOwnerType(SocialActivityCounterConstants.TYPE_ACTOR);
    } else if (activityCounterName.equals(SocialActivityCounterConstants.NAME_POPULARITY)) {

      activityCounterDefinition.setOwnerType(SocialActivityCounterConstants.TYPE_ASSET);

      activityCounterName = SocialActivityCounterConstants.NAME_CONTRIBUTION;
    } else {
      throw new IllegalArgumentException();
    }

    activityCounterDefinition.setEnabled(actionJSONObject.getBoolean("active"));
    activityCounterDefinition.setIncrement(
        actionJSONObject.getInt(activityCounterName + "Increment"));
    activityCounterDefinition.setLimitPeriod(
        actionJSONObject.getInt(activityCounterName + "LimitPeriod"));
    activityCounterDefinition.setLimitValue(
        actionJSONObject.getInt(activityCounterName + "LimitValue"));

    return activityCounterDefinition;
  }
  /**
   * Adds or increments activity counters related to an activity. This method is called
   * asynchronously from the social activity service when the user performs an activity defined in
   * </code>liferay-social.xml</code>.
   *
   * <p>This method first calls the activity processor class, if there is one defined for the
   * activity, checks for limits and increments all the counters that belong to the activity.
   * Afterwards, it processes the activity with respect to achievement classes, if any. Lastly it
   * increments the built-in <code>user.activities</code> and <code>asset.activities</code>
   * counters.
   *
   * @param activity the social activity
   * @throws PortalException if an expected group or expected previous activity counters could not
   *     be found
   */
  @Override
  public void addActivityCounters(SocialActivity activity) throws PortalException {

    if (!socialActivitySettingLocalService.isEnabled(
        activity.getGroupId(), activity.getClassNameId())) {

      return;
    }

    if (!socialActivitySettingLocalService.isEnabled(
        activity.getGroupId(), activity.getClassNameId(), activity.getClassPK())) {

      return;
    }

    if ((activity.getType() == SocialActivityConstants.TYPE_MOVE_ATTACHMENT_TO_TRASH)
        || (activity.getType() == SocialActivityConstants.TYPE_MOVE_TO_TRASH)) {

      disableActivityCounters(activity.getClassNameId(), activity.getClassPK());

      return;
    }

    if ((activity.getType() == SocialActivityConstants.TYPE_RESTORE_ATTACHMENT_FROM_TRASH)
        || (activity.getType() == SocialActivityConstants.TYPE_RESTORE_FROM_TRASH)) {

      enableActivityCounters(activity.getClassNameId(), activity.getClassPK());

      return;
    }

    User user = userPersistence.findByPrimaryKey(activity.getUserId());

    SocialActivityDefinition activityDefinition =
        socialActivitySettingLocalService.getActivityDefinition(
            activity.getGroupId(), activity.getClassName(), activity.getType());

    if ((activityDefinition == null) || !activityDefinition.isCountersEnabled()) {

      return;
    }

    SocialActivityProcessor activityProcessor = activityDefinition.getActivityProcessor();

    if (activityProcessor != null) {
      activityProcessor.processActivity(activity);
    }

    AssetEntry assetEntry = activity.getAssetEntry();

    User assetEntryUser = userPersistence.findByPrimaryKey(assetEntry.getUserId());

    List<SocialActivityCounter> activityCounters = new ArrayList<>();

    for (SocialActivityCounterDefinition activityCounterDefinition :
        activityDefinition.getActivityCounterDefinitions()) {

      if (isAddActivityCounter(user, assetEntryUser, assetEntry, activityCounterDefinition)) {

        SocialActivityCounter activityCounter =
            addActivityCounter(activity.getGroupId(), user, activity, activityCounterDefinition);

        activityCounters.add(activityCounter);
      }
    }

    SocialActivityCounter assetActivitiesCounter = null;

    if (!assetEntryUser.isDefaultUser() && assetEntryUser.isActive() && assetEntry.isVisible()) {

      assetActivitiesCounter = addAssetActivitiesCounter(activity);
    }

    SocialActivityCounter userActivitiesCounter = null;

    if (!user.isDefaultUser() && user.isActive()) {
      userActivitiesCounter = addUserActivitiesCounter(activity);
    }

    for (SocialActivityCounter activityCounter : activityCounters) {
      SocialActivityCounterDefinition activityCounterDefinition =
          activityDefinition.getActivityCounterDefinition(activityCounter.getName());

      if (checkActivityLimit(user, activity, activityCounterDefinition)) {
        incrementActivityCounter(activityCounter, activityCounterDefinition);
      }
    }

    if (assetActivitiesCounter != null) {
      incrementActivityCounter(assetActivitiesCounter, _assetActivitiesActivityCounterDefinition);
    }

    if (userActivitiesCounter != null) {
      incrementActivityCounter(userActivitiesCounter, _userActivitiesActivityCounterDefinition);
    }

    for (SocialAchievement achievement : activityDefinition.getAchievements()) {

      achievement.processActivity(activity);
    }
  }