/**
   * Returns a CSV line for the given LoggingObject - containing all properties in the exact same
   * way as in the config file - excluding those which could not be retrieved, i.e. for which no
   * PropertyDescriptor could be created
   *
   * @param loggingObject the LoggingObject for which a CSV line should be created
   * @return the CSV line representing the given LoggingObject
   */
  public String getCSVRow(LoggingObject loggingObject, boolean anonymize, Long resourceableId) {
    List<String> loggingObjectList = new ArrayList<String>();
    for (Iterator<PropertyDescriptor> it = orderedExportedPropertyDescriptors.iterator();
        it.hasNext(); ) {
      PropertyDescriptor pd = it.next();

      String strValue = "";
      try {
        Object value = pd.getReadMethod().invoke(loggingObject, (Object[]) null);
        if (value != null) {
          strValue = String.valueOf(value);
        }
        if (anonymize && anonymizedProperties.contains(pd.getName())) {
          // do anonymization
          strValue = makeAnonymous(String.valueOf(value), resourceableId);
        }
      } catch (IllegalArgumentException e) {
        // nothing to do
      } catch (IllegalAccessException e) {
        // nothing to do
      } catch (InvocationTargetException e) {
        // nothing to do
      }
      loggingObjectList.add(strValue);
    }

    return StringHelper.formatAsCSVString(loggingObjectList);
  }
 /**
  * Returns the CSV Header line containing all property names in the exact same way as in the
  * config file - excluding those properties which could not be retrieved, i.e. for which no
  * PropertyDescriptor could be created
  *
  * @return the CSV Header line containing all property names in the exact same way as in the
  *     config file - excluding those properties which could not be retrieved, i.e. for which no
  *     PropertyDescriptor could be created
  */
 public String getCSVHeader() {
   List<String> propertyNames = new ArrayList<String>();
   for (Iterator<PropertyDescriptor> it = orderedExportedPropertyDescriptors.iterator();
       it.hasNext(); ) {
     PropertyDescriptor pd = it.next();
     propertyNames.add(pd.getName());
   }
   return StringHelper.formatAsCSVString(propertyNames);
 }
  /**
   * @see
   *     org.olat.core.gui.components.form.flexible.impl.FormBasicController#validateFormLogic(org.olat.core.gui.UserRequest)
   */
  @Override
  public boolean validateFormLogic(UserRequest ureq) {
    // 1) Check valid group names
    if (!StringHelper.containsNonWhitespace(businessGroupName.getValue())) {
      businessGroupName.setErrorKey("form.legende.mandatory", new String[] {});
      return false;
    }

    if (bulkMode) {
      // check all names to be valid and check that at least one is entered
      // e.g. find "," | " , " | ",,," errors => no group entered
      String selectionAsCsvStr = businessGroupName.getValue();
      String[] activeSelection =
          selectionAsCsvStr != null ? selectionAsCsvStr.split(",") : new String[] {};
      validNames = new HashSet<String>();
      Set<String> wrongNames = new HashSet<String>();
      boolean nameTooLong = false;
      for (int i = 0; i < activeSelection.length; i++) {
        String currentName = activeSelection[i].trim();
        if (currentName.getBytes().length > BusinessGroup.MAX_GROUP_NAME_LENGTH) {
          nameTooLong = true;
        } else if ((currentName).matches(BusinessGroup.VALID_GROUPNAME_REGEXP)) {
          validNames.add(currentName);
        } else {
          wrongNames.add(currentName);
        }
      }
      if (validNames.size() == 0 && wrongNames.size() == 0 && !nameTooLong) {
        // no valid name and no invalid names, this is no names
        businessGroupName.setErrorKey("create.form.error.illegalName", new String[] {});
        return false;
      } else if (nameTooLong) {
        businessGroupName.setErrorKey(
            "create.form.error.nameTooLong",
            new String[] {BusinessGroup.MAX_GROUP_NAME_LENGTH + ""});
        return false;
      } else if (wrongNames.size() == 1) {
        // one invalid name
        businessGroupName.setErrorKey("create.form.error.illegalName", new String[] {});
        return false;
      } else if (wrongNames.size() > 1) {
        // two or more invalid names
        String[] args = new String[] {StringHelper.formatAsCSVString(wrongNames)};
        businessGroupName.setErrorKey("create.form.error.illegalNames", args);
        return false;
      }
    } else {
      String groupName = businessGroupName.getValue();
      if (groupName.getBytes().length > BusinessGroup.MAX_GROUP_NAME_LENGTH) {
        businessGroupName.setErrorKey(
            "create.form.error.nameTooLong",
            new String[] {BusinessGroup.MAX_GROUP_NAME_LENGTH + ""});
        return false;
      } else if (!(groupName).matches(BusinessGroup.VALID_GROUPNAME_REGEXP)) {
        businessGroupName.setErrorKey("create.form.error.illegalName", new String[] {});
        return false;
      }
      if (businessGroupName.hasError()) {
        return false; // auto-validations from form, return false, because of that
                      // clearError()-calls everywhere...
      }
    }
    // all group name tests passed
    businessGroupName.clearError();

    // 2) Check valid description
    if (businessGroupDescription.getValue().length() > 4000) {
      businessGroupDescription.setErrorKey("input.toolong", new String[] {"4000"});
      return false;
    }
    businessGroupDescription.clearError();

    // 3) Check auto close settings
    boolean disableWaitingListOk = true;
    if (businessGroup != null) {
      int waitingPartipiciantSize =
          businessGroupService.countMembers(businessGroup, GroupRoles.waiting.name());
      if ((businessGroup.getWaitingListEnabled()).booleanValue()
          && !isWaitingListEnabled()
          && (waitingPartipiciantSize > 0)) {
        enableAutoCloseRanks.setErrorKey("form.error.disableNonEmptyWaitingList", new String[] {});
        disableWaitingListOk = false;
        setEnableWaitingList(true);
        return false;
      }
    }
    enableAutoCloseRanks.clearError();

    if (disableWaitingListOk) {
      // 4) Check min / max settings
      String maxValue = null;
      if (StringHelper.containsNonWhitespace(businessGroupMaximumMembers.getValue())) {
        maxValue = businessGroupMaximumMembers.getValue();
      }
      String minValue = null;
      if (StringHelper.containsNonWhitespace(businessGroupMinimumMembers.getValue())) {
        minValue = businessGroupMinimumMembers.getValue();
      }
      if (isWaitingListEnabled() && (maxValue == null || minValue == "")) {
        enableWaitingList.setErrorKey("create.form.error.enableWaitinglist", new String[] {});
        return false;
      }
      enableWaitingList.clearError();

      // 5) Check auto close - waiting list dependency
      if (isAutoCloseRanksEnabled() && !isWaitingListEnabled()) {
        enableAutoCloseRanks.setErrorKey("create.form.error.enableAutoCloseRanks", new String[] {});
        return false;
      }
      enableAutoCloseRanks.clearError();

      // 6) Check min/max validity
      if (!businessGroupMaximumMembers
          .getValue()
          .matches("^\\p{Space}*(\\p{Digit}*)\\p{Space}*$")) {
        businessGroupMaximumMembers.setErrorKey("create.form.error.numberOrNull", new String[] {});
        return false;
      }
      if (!businessGroupMinimumMembers
          .getValue()
          .matches("^\\p{Space}*(\\p{Digit}*)\\p{Space}*$")) {
        businessGroupMaximumMembers.setErrorKey("create.form.error.numberOrNull", new String[] {});
        return false;
      }
      businessGroupMaximumMembers.clearError();
    }
    // group name duplication test passed
    businessGroupName.clearError();

    // all checks passed
    return true;
  }