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