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