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
034 *      by demand in subclasses
035 */
036public abstract class AbstractViolationReporter
037    extends AbstractAutomaticBean {
038
039    /** The severity level of any violations found. */
040    private SeverityLevel severityLevel = SeverityLevel.ERROR;
041
042    /** The identifier of the reporter. */
043    private String id;
044
045    /**
046     * Creates a new {@code AbstractViolationReporter} instance.
047     */
048    protected AbstractViolationReporter() {
049        // no code by default
050    }
051
052    /**
053     * Returns the severity level of the violations generated by this module.
054     *
055     * @return the severity level
056     * @see SeverityLevel
057     * @see Violation#getSeverityLevel
058     * @noinspection WeakerAccess
059     * @noinspectionreason we avoid 'protected' when possible
060     */
061    public final SeverityLevel getSeverityLevel() {
062        return severityLevel;
063    }
064
065    /**
066     * Sets the severity level.  The string should be one of the names
067     * defined in the {@code SeverityLevel} class.
068     *
069     * @param severity  The new severity level
070     * @see SeverityLevel
071     */
072    public final void setSeverity(String severity) {
073        severityLevel = SeverityLevel.getInstance(severity);
074    }
075
076    /**
077     *  Get the severity level's name.
078     *
079     *  @return  the check's severity level name.
080     *  @noinspection WeakerAccess
081     *  @noinspectionreason WeakerAccess - we avoid 'protected' when possible
082     */
083    public final String getSeverity() {
084        return severityLevel.getName();
085    }
086
087    /**
088     * Returns the identifier of the reporter. Can be null.
089     *
090     * @return the id
091     */
092    public final String getId() {
093        return id;
094    }
095
096    /**
097     * Sets the identifier of the reporter. Can be null.
098     *
099     * @param id the id
100     */
101    public final void setId(final String id) {
102        this.id = id;
103    }
104
105    /**
106     * Returns an unmodifiable map instance containing the custom messages
107     * for this configuration.
108     *
109     * @return unmodifiable map containing custom messages
110     */
111    protected Map<String, String> getCustomMessages() {
112        return getConfiguration().getMessages();
113    }
114
115    /**
116     * Returns the message bundle name resource bundle that contains the messages
117     * used by this module.
118     *
119     * <p>
120     * The default implementation expects the resource files to be named
121     * messages.properties, messages_de.properties, etc. The file must
122     * be placed in the same package as the module implementation.
123     * </p>
124     *
125     * <p>
126     * Example: If you write com/foo/MyCoolCheck, create resource files
127     * com/foo/messages.properties, com/foo/messages_de.properties, etc.
128     * </p>
129     *
130     * @return name of a resource bundle that contains the messages
131     *     used by this module.
132     */
133    protected String getMessageBundle() {
134        final String className = getClass().getName();
135        return getMessageBundle(className);
136    }
137
138    /**
139     * For unit tests, especially with a class with no package name.
140     *
141     * @param className class name of the module.
142     * @return name of a resource bundle that contains the messages
143     *     used by the module.
144     */
145    private static String getMessageBundle(final String className) {
146        final String messageBundle;
147        final int endIndex = className.lastIndexOf('.');
148        final String messages = "messages";
149        if (endIndex == -1) {
150            messageBundle = messages;
151        }
152        else {
153            final String packageName = className.substring(0, endIndex);
154            messageBundle = packageName + "." + messages;
155        }
156        return messageBundle;
157    }
158
159    @Override
160    protected void finishLocalSetup() throws CheckstyleException {
161        // No code by default
162    }
163
164    /**
165     * Log a message that has no column information.
166     *
167     * @param line the line number where the audit event was found
168     * @param key the message that describes the audit event
169     * @param args the details of the message
170     *
171     * @see java.text.MessageFormat
172     */
173    // -@cs[CustomDeclarationOrder] CustomDeclarationOrder does not treat groups of
174    // overloaded methods. See https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/414
175    public abstract void log(int line, String key, Object... args);
176
177    /**
178     * Log a message that has column information.
179     *
180     * @param line the line number where the audit event was found
181     * @param col the column number where the audit event was found
182     * @param key the message that describes the audit event
183     * @param args the details of the message
184     *
185     * @see java.text.MessageFormat
186     */
187    // -@cs[CustomDeclarationOrder] CustomDeclarationOrder does not treat groups of
188    // overloaded methods. See https://github.com/sevntu-checkstyle/sevntu.checkstyle/issues/414
189    public abstract void log(int line, int col, String key,
190            Object... args);
191
192}