<commit_before>package org.pharmgkb.common.util;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;
import com.google.common.base.Preconditions;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils;
import org.checkerframework.checker.nullness.qual.Nullable;


/**
 * This is a helper class that handles all the lookup work for enums.
 *
 * @author <NAME>
 */
public class ExtendedEnumHelper<T extends ExtendedEnum> {
  private static final Map<Class, ExtendedEnumHelper> sf_enumMap = new HashMap<>();
  private Map<Integer, T> m_idMap = new TreeMap<>();
  private Map<String, T> m_shortNameMap = new TreeMap<>();
  private Map<String, T> m_displayNameMap = new TreeMap<>();
  private Map<String, T> m_lcNameMap = new TreeMap<>();
  private Map<String, T> m_additionalNamesMap = new TreeMap<>();


  /**
   * This constructor registers the {@link ExtendedEnum} for conversion by BeanUtils.
   */
  public ExtendedEnumHelper(Class clz) {
    Preconditions.checkNotNull(clz, "clz is null");
    ConvertUtils.register(ExtendedEnumConverter.getConverter(), clz);
  }


  /**
   * Adds the given enum to the maps.
   *
   * @throws IllegalStateException if the enum being added has a id, name or display name that's
   * already being used
   * @throws IllegalArgumentException if the short name has a space in it
   */
  public void add(T theEnum, int id, String shortName, @Nullable String displayName,
      @Nullable String... additionalNames) {

    Preconditions.checkArgument(!m_idMap.containsKey(id), "Duplicate ID '%s' for %s", id,
        theEnum.getClass().getSimpleName());

    Preconditions.checkNotNull(shortName, "shortName is null");
    String strippedShortName = StringUtils.stripToNull(shortName);
    Preconditions.checkArgument(strippedShortName != null, "Empty shortName for %s",
        theEnum.getClass().getSimpleName());
    Preconditions.checkArgument(!strippedShortName.contains(" "), "Spaces in shortName for %s",
        theEnum.getClass().getSimpleName());
    Preconditions.checkArgument(!StringUtils.isNumeric(strippedShortName), "Numeric shortName for %s",
        theEnum.getClass().getSimpleName());
    Preconditions.checkArgument(!m_shortNameMap.containsKey(strippedShortName),
        "Duplicate shortName '%s' for %s", strippedShortName, theEnum.getClass().getSimpleName());

    String strippedDisplayName = StringUtils.stripToNull(displayName);
    if (strippedDisplayName != null) {
      Preconditions.checkArgument(!m_displayNameMap.containsKey(strippedDisplayName),
          "Duplicate displayName '%s' for %s", strippedDisplayName, theEnum.getClass().getSimpleName());
    }

    m_idMap.put(id, theEnum);

    m_shortNameMap.put(strippedShortName, theEnum);
    m_lcNameMap.put(strippedShortName.toLowerCase(), theEnum);

    if (strippedDisplayName != null) {
      m_displayNameMap.put(strippedDisplayName, theEnum);
      m_lcNameMap.put(strippedDisplayName.toLowerCase(), theEnum);
    }
    if (!sf_enumMap.containsKey(theEnum.getClass())) {
      sf_enumMap.put(theEnum.getClass(), this);
    }
    if (additionalNames != null) {
      for (String additionalName : additionalNames) {
        if (additionalName != null) {
          m_additionalNamesMap.put(additionalName, theEnum);
          ExtendedEnum oldVal = m_lcNameMap.put(additionalName.toLowerCase(), theEnum);
          if (oldVal != null && oldVal != theEnum) {
            throw new IllegalArgumentException(String.format("Additional name '%s' for %s mapped to %s and %s",
                additionalName, theEnum.getClass().getSimpleName(), oldVal, theEnum));
          }
        }
      }
    }
  }


  /**
   * Looks for the enum with the given Id.
   */
  public @Nullable T lookupById(int id) {
    return m_idMap.get(id);
  }

  /**
   * Looks for the enum with the given name.
   *
   * @return the enum for the given name, or null if none can be found
   */
  public @Nullable T lookupByName(String name) {
    Preconditions.checkNotNull(name, "name is null");

    if (m_displayNameMap.containsKey(name)) {
      return m_displayNameMap.get(name);
    }
    if (m_shortNameMap.containsKey(name)) {
      return m_shortNameMap.get(name);
    }
    if (m_additionalNamesMap.containsKey(name)) {
      return m_additionalNamesMap.get(name);
    }
    return m_lcNameMap.get(name.toLowerCase());
  }


  /**
   * If value is an integer return enum with given Id, otherwise return enum with given name.
   * Helps provide functionality for type conversion in RESTful services.
   */
  public @Nullable T fromString(@Nullable String value) {

    if (value == null) {
      return null;
    }
    if (StringUtils.isNumeric(value)) {
      return lookupById(Integer.parseInt(value));
    } else {
      return lookupByName(value);
    }
  }


  /**
   * Gets all the enums sorted by Id.
   */
  public Collection<T> getAllSortedById() {
    return m_idMap.values();
  }

  /**
   * Gets all the enums sorted by name.
   */<commit_msg>chore: convert studyType in StudyParameters to an actual enum collection<commit_after>package org.pharmgkb.common.util;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.regex.Pattern;
import com.google.common.base.Preconditions;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.WordUtils;
import org.checkerframework.checker.nullness.qual.Nullable;


/**
 * This is a helper class that handles all the lookup work for enums.
 *
 * @author <NAME>
 */
public class ExtendedEnumHelper<T extends ExtendedEnum> {
  private static final Map<Class, ExtendedEnumHelper> sf_enumMap = new HashMap<>();
  private Map<Integer, T> m_idMap = new TreeMap<>();
  private Map<String, T> m_shortNameMap = new TreeMap<>();
  private Map<String, T> m_displayNameMap = new TreeMap<>();
  private Map<String, T> m_lcNameMap = new TreeMap<>();
  private Map<String, T> m_additionalNamesMap = new TreeMap<>();


  /**
   * This constructor registers the {@link ExtendedEnum} for conversion by BeanUtils.
   */
  public ExtendedEnumHelper(Class clz) {
    Preconditions.checkNotNull(clz, "clz is null");
    ConvertUtils.register(ExtendedEnumConverter.getConverter(), clz);
  }


  /**
   * Adds the given enum to the maps.
   *
   * @throws IllegalStateException if the enum being added has a id, name or display name that's
   * already being used
   * @throws IllegalArgumentException if the short name has a space in it
   */
  public void add(T theEnum, int id, String shortName, @Nullable String displayName,
      @Nullable String... additionalNames) {

    Preconditions.checkArgument(!m_idMap.containsKey(id), "Duplicate ID '%s' for %s", id,
        theEnum.getClass().getSimpleName());

    Preconditions.checkNotNull(shortName, "shortName is null");
    String strippedShortName = StringUtils.stripToNull(shortName);
    Preconditions.checkArgument(strippedShortName != null, "Empty shortName for %s",
        theEnum.getClass().getSimpleName());
    Preconditions.checkArgument(!strippedShortName.contains(" "), "Spaces in shortName for %s",
        theEnum.getClass().getSimpleName());
    Preconditions.checkArgument(!StringUtils.isNumeric(strippedShortName), "Numeric shortName for %s",
        theEnum.getClass().getSimpleName());
    Preconditions.checkArgument(!m_shortNameMap.containsKey(strippedShortName),
        "Duplicate shortName '%s' for %s", strippedShortName, theEnum.getClass().getSimpleName());

    String strippedDisplayName = StringUtils.stripToNull(displayName);
    if (strippedDisplayName != null) {
      Preconditions.checkArgument(!m_displayNameMap.containsKey(strippedDisplayName),
          "Duplicate displayName '%s' for %s", strippedDisplayName, theEnum.getClass().getSimpleName());
    }

    m_idMap.put(id, theEnum);

    m_shortNameMap.put(strippedShortName, theEnum);
    m_lcNameMap.put(strippedShortName.toLowerCase(), theEnum);

    if (strippedDisplayName != null) {
      m_displayNameMap.put(strippedDisplayName, theEnum);
      m_lcNameMap.put(strippedDisplayName.toLowerCase(), theEnum);
    }
    if (!sf_enumMap.containsKey(theEnum.getClass())) {
      sf_enumMap.put(theEnum.getClass(), this);
    }
    if (additionalNames != null) {
      for (String additionalName : additionalNames) {
        if (additionalName != null) {
          m_additionalNamesMap.put(additionalName, theEnum);
          ExtendedEnum oldVal = m_lcNameMap.put(additionalName.toLowerCase(), theEnum);
          if (oldVal != null && oldVal != theEnum) {
            throw new IllegalArgumentException(String.format("Additional name '%s' for %s mapped to %s and %s",
                additionalName, theEnum.getClass().getSimpleName(), oldVal, theEnum));
          }
        }
      }
    }
  }


  /**
   * Looks for the enum with the given Id.
   */
  public @Nullable T lookupById(int id) {
    return m_idMap.get(id);
  }

  /**
   * Looks for the enum with the given name.
   *
   * @return the enum for the given name, or null if none can be found
   */
  public @Nullable T lookupByName(String name) {
    Preconditions.checkNotNull(name, "name is null");

    if (m_displayNameMap.containsKey(name)) {
      return m_displayNameMap.get(name);
    }
    if (m_shortNameMap.containsKey(name)) {
      return m_shortNameMap.get(name);
    }
    if (m_additionalNamesMap.containsKey(name)) {
      return m_additionalNamesMap.get(name);
    }
    return m_lcNameMap.get(name.toLowerCase());
  }

  /**
   * Looks for the enum with the given name and returns an {@link Optional} result
   * @param name a display, short, or additional name to lookup, required
   * @return a non-null Optional wrapper of the enum found
   */
  public Optional<T> lookupByNameOptional(String name) {
    return Optional.ofNullable(lookupByName(name));
  }


  /**
   * If value is an integer return enum with given Id, otherwise return enum with given name.
   * Helps provide functionality for type conversion in RESTful services.
   */
  public @Nullable T fromString(@Nullable String value) {

    if (value == null) {
      return null;
    }
    if (StringUtils.isNumeric(value)) {
      return lookupById(Integer.parseInt(value));
    } else {
      return lookupByName(value);
    }
  }


  /**
   * Gets all the enums sorted by Id.
   */
  public Collection<T> getAllSortedById() {
    return m_idMap.values();
  }

  /**
   * Gets all the enums sorted by name.
   */
{'fraction_non_alphanumeric': 0.11364907700913668, 'fraction_numerical': 0.00018646280067126608, 'mean_word_length': 3.704824561403509, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3018820', 'n_tokens_mistral': 3184, 'n_tokens_neox': 3142, 'n_words': 819}