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