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