code: ///////////////////////////////////////////////////////////////////////////////////////////////
  // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
  // Copyright (C) 2001-2023 the original author or authors.
  //
  // This library is free software; you can redistribute it and/or
  // modify it under the terms of the GNU Lesser General Public
  // License as published by the Free Software Foundation; either
  // version 2.1 of the License, or (at your option) any later version.
  //
  // This library is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  // Lesser General Public License for more details.
  //
  // You should have received a copy of the GNU Lesser General Public
  // License along with this library; if not, write to the Free Software
  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  ///////////////////////////////////////////////////////////////////////////////////////////////
  
  package com.puppycrawl.tools.checkstyle.api;
  
  import java.util.Map;
  
  import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean;
  
  /**
   * Serves as an abstract base class for all modules that report inspection
   * findings. Such modules have a Severity level which is used for the
   * {@link Violation violations} that are created by the module.
   *
   * @noinspection NoopMethodInAbstractClass
   * @noinspectionreason NoopMethodInAbstractClass - we allow each check to
   *      define these methods, as needed. They should be overridden only
   *      by demand in subclasses
   */
  public abstract class AbstractViolationReporter
      extends AbstractAutomaticBean {
  
      /** The severity level of any violations found. */
      private SeverityLevel severityLevel = SeverityLevel.ERROR;
  
      /** The identifier of the reporter. */
      private String id;
  
      /**
       * Returns the severity level of the violations generated by this module.
       *
       * @return the severity level
       * @see SeverityLevel
       * @see Violation#getSeverityLevel
       * @noinspection WeakerAccess
       * @noinspectionreason we avoid 'protected' when possible
       */
      public final SeverityLevel getSeverityLevel() {
          return severityLevel;
      }
  
      /**
       * Sets the severity level.  The string should be one of the names
       * defined in the {@code SeverityLevel} class.
       *
       * @param severity  The new severity level
       * @see SeverityLevel
       */
      public final void setSeverity(String severity) {
          severityLevel = SeverityLevel.getInstance(severity);
      }
  
      /**
       *  Get the severity level's name.
       *
       *  @return  the check's severity level name.
       *  @noinspection WeakerAccess
       *  @noinspectionreason WeakerAccess - we avoid 'protected' when possible
       */
      public final String getSeverity() {
          return severityLevel.getName();
      }
  
      /**
       * Returns the identifier of the reporter. Can be null.
       *
       * @return the id
       */
      public final String getId() {
          return id;
      }
  
      /**
       * Sets the identifier of the reporter. Can be null.
       *
       * @param id the id
       */
      public final void setId(final String id) {
          this.id = id;
      }
  
      /**
       * Returns an unmodifiable map instance containing the custom messages
       * for this configuration.
       *
       * @return unmodifiable map containing custom messages
       */
      protected Map<String, String> getCustomMessages() {
          return getConfiguration().getMessages();
      }
  
      /**
       * Returns the message bundle name resource bundle that contains the messages
       * used by this module.
       * <p>
       * The default implementation expects the resource files to be named
       * messages.properties, messages_de.properties, etc. The file must
       * be placed in the same package as the module implementation.
       * </p>
       * <p>
       * Example: If you write com/foo/MyCoolCheck, create resource files
       * com/foo/messages.properties, com/foo/messages_de.properties, etc.
       * </p>
       *
       * @return name of a resource bundle that contains the messages
       *     used by this module.
       */
      protected String getMessageBundle() {
          final String className = getClass().getName();
          return getMessageBundle(className);
      }
  
      /**
       * For unit tests, especially with a class with no package name.
       *
       * @param className class name of the module.
       * @return name of a resource bundle that contains the messages
       *     used by the module.
       */
      private static String getMessageBundle(final String className) {
          final String messageBundle;
          final int endIndex = className.lastIndexOf('.');
          final String messages = "messages";
          if (endIndex == -1) {
              messageBundle = messages;
          }
          else {
              final String packageName = className.substring(0, endIndex);
              messageBundle = packageName + "." + messages;
          }
          return messageBundle;
      }
  
      @Override
      protected void finishLocalSetup() throws CheckstyleException {
          // No code by default
      }
  
      /**
       * Log a message that has no column information.
       *
       * @param line the line number where the audit event was found
       * @param key the message that describes the audit event
       * @param args the details of the message
       *
       * @see java.text.MessageFormat
       */
      // -@cs[CustomDeclarationOrder] CustomDeclarationOrder does not treat groups of
      // overloaded methods. See https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/414
      public abstract void log(int line, String key, Object... args);
  
      /**
       * Log a message that has column information.
       *
       * @param line the line number where the audit event was found
       * @param col the column number where the audit event was found
       * @param key the message that describes the audit event
       * @param args the details of the message
       *
       * @see java.text.MessageFormat
       */
      // -@cs[CustomDeclarationOrder] CustomDeclarationOrder does not treat groups of
      // overloaded methods. See https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/414
      public abstract void log(int line, int col, String key,
              Object... args);
  
  }
  