001///////////////////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
003// Copyright (C) 2001-2026 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018///////////////////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.api;
021
022import java.util.Map;
023
024import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean;
025
026/**
027 * Serves as an abstract base class for all modules that report inspection
028 * findings. Such modules have a Severity level which is used for the
029 * {@link Violation violations} that are created by the module.
030 *
031 * @noinspection NoopMethodInAbstractClass
032 * @noinspectionreason NoopMethodInAbstractClass - we allow each check to
033 *      define these methods, as needed. They should be overridden only by demand in subclasses
034 */
035public abstract class AbstractViolationReporter extends AbstractAutomaticBean {
036
037    /** The severity level of any violations found. */
038    private SeverityLevel severityLevel = SeverityLevel.ERROR;
039
040    /** The identifier of the reporter. */
041    private String id;
042
043    /**
044     * Creates a new {@code AbstractViolationReporter} instance.
045     */
046    protected AbstractViolationReporter() {
047        // no code by default
048    }
049
050    /**
051     * Returns the severity level of the violations generated by this module.
052     *
053     * @return the severity level
054     * @see SeverityLevel
055     * @see Violation#getSeverityLevel
056     * @noinspection WeakerAccess
057     * @noinspectionreason we avoid 'protected' when possible
058     */
059    public final SeverityLevel getSeverityLevel() {
060        return severityLevel;
061    }
062
063    /**
064     * Sets the severity level.  The string should be one of the names
065     * defined in the {@code SeverityLevel} class.
066     *
067     * @param severity  The new severity level
068     * @see SeverityLevel
069     */
070    public final void setSeverity(String severity) {
071        severityLevel = SeverityLevel.getInstance(severity);
072    }
073
074    /**
075     *  Get the severity level's name.
076     *
077     *  @return  the check's severity level name.
078     *  @noinspection WeakerAccess
079     *  @noinspectionreason WeakerAccess - we avoid 'protected' when possible
080     */
081    public final String getSeverity() {
082        return severityLevel.getName();
083    }
084
085    /**
086     * Returns the identifier of the reporter. Can be null.
087     *
088     * @return the id
089     */
090    public final String getId() {
091        return id;
092    }
093
094    /**
095     * Sets the identifier of the reporter. Can be null.
096     *
097     * @param id the id
098     */
099    public final void setId(final String id) {
100        this.id = id;
101    }
102
103    /**
104     * Returns an unmodifiable map instance containing the custom messages for this configuration.
105     *
106     * @return unmodifiable map containing custom messages
107     */
108    protected Map<String, String> getCustomMessages() {
109        return getConfiguration().getMessages();
110    }
111
112    /**
113     * Returns the message bundle name resource bundle that contains the messages
114     * used by this module.
115     *
116     * <p>
117     * The default implementation expects the resource files to be named
118     * messages.properties, messages_de.properties, etc. The file must
119     * be placed in the same package as the module implementation.
120     * </p>
121     *
122     * <p>
123     * Example: If you write com/foo/MyCoolCheck, create resource files
124     * com/foo/messages.properties, com/foo/messages_de.properties, etc.
125     * </p>
126     *
127     * @return name of a resource bundle that contains the messages used by this module.
128     */
129    protected String getMessageBundle() {
130        final String className = getClass().getName();
131        return getMessageBundle(className);
132    }
133
134    /**
135     * For unit tests, especially with a class with no package name.
136     *
137     * @param className class name of the module.
138     * @return name of a resource bundle that contains the messages used by the module.
139     */
140    private static String getMessageBundle(final String className) {
141        final String messageBundle;
142        final int endIndex = className.lastIndexOf('.');
143        final String messages = "messages";
144        if (endIndex == -1) {
145            messageBundle = messages;
146        }
147        else {
148            final String packageName = className.substring(0, endIndex);
149            messageBundle = packageName + "." + messages;
150        }
151        return messageBundle;
152    }
153
154    @Override
155    protected void finishLocalSetup() throws CheckstyleException {
156        // No code by default
157    }
158
159    /**
160     * Log a message that has no column information.
161     *
162     * @param line the line number where the audit event was found
163     * @param key the message that describes the audit event
164     * @param args the details of the message
165     *
166     * @see java.text.MessageFormat
167     */
168    // -@cs[CustomDeclarationOrder] CustomDeclarationOrder does not treat groups of
169    // overloaded methods. See https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/414
170    public abstract void log(int line, String key, Object... args);
171
172    /**
173     * Log a message that has column information.
174     *
175     * @param line the line number where the audit event was found
176     * @param col the column number where the audit event was found
177     * @param key the message that describes the audit event
178     * @param args the details of the message
179     *
180     * @see java.text.MessageFormat
181     */
182    // -@cs[CustomDeclarationOrder] CustomDeclarationOrder does not treat groups of
183    // overloaded methods. See https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/414
184    public abstract void log(int line, int col, String key,
185            Object... args);
186
187}