Patch from David Schneider to add Severity to logged messages.
This commit is contained in:
parent
5d4dd44322
commit
53197d9be9
|
|
@ -18,10 +18,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
|
||||
|
||||
import java.util.EventObject;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
|
||||
import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
|
||||
|
||||
/**
|
||||
* Raw event for audit.
|
||||
* <p>
|
||||
|
|
@ -112,6 +113,14 @@ public final class AuditEvent
|
|||
return mMessage.getColumnNo();
|
||||
}
|
||||
|
||||
/** @return the audit event severity level **/
|
||||
public SeverityLevel getSeverityLevel()
|
||||
{
|
||||
return (mMessage == null)
|
||||
? SeverityLevel.WARNING
|
||||
: mMessage.getSeverityLevel();
|
||||
}
|
||||
|
||||
/** @return the localized message **/
|
||||
public LocalizedMessage getLocalizedMessage()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,13 +83,12 @@ public class DefaultLogger
|
|||
**/
|
||||
public void addError(AuditEvent aEvt)
|
||||
{
|
||||
String fileName = aEvt.getFileName();
|
||||
String message = aEvt.getMessage();
|
||||
final String fileName = aEvt.getFileName();
|
||||
final String message = aEvt.getMessage();
|
||||
|
||||
// avoid StringBuffer.expandCapacity
|
||||
int bufLen = fileName.length() + message.length() + 12;
|
||||
|
||||
StringBuffer sb = new StringBuffer(bufLen);
|
||||
final int bufLen = fileName.length() + message.length() + 12;
|
||||
final StringBuffer sb = new StringBuffer(bufLen);
|
||||
|
||||
sb.append(fileName);
|
||||
sb.append(':').append(aEvt.getLine());
|
||||
|
|
|
|||
|
|
@ -111,6 +111,9 @@ public class XMLLogger
|
|||
if (aEvt.getColumn() > 0) {
|
||||
mWriter.print(" column=\"" + aEvt.getColumn() + "\"");
|
||||
}
|
||||
mWriter.print(" severity=\""
|
||||
+ aEvt.getSeverityLevel().getName()
|
||||
+ "\"");
|
||||
mWriter.println(" message=\"" + encode(aEvt.getMessage()) + "\"/>");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package com.puppycrawl.tools.checkstyle.api;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* The base class for checks.
|
||||
*
|
||||
|
|
@ -46,6 +47,9 @@ public abstract class Check extends AutomaticBean
|
|||
/** the tab with for column reporting */
|
||||
private int mTabWidth = 8; // meaningful default
|
||||
|
||||
/** the severity level of any violations found */
|
||||
private SeverityLevel mSeverityLevel = SeverityLevel.WARNING;
|
||||
|
||||
/** current class loader */
|
||||
private ClassLoader mLoader =
|
||||
Thread.currentThread().getContextClassLoader();
|
||||
|
|
@ -223,6 +227,38 @@ public abstract class Check extends AutomaticBean
|
|||
mTabWidth = aTabWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the severity level of the check.
|
||||
* @return the severity level
|
||||
* @see com.puppycrawl.tools.checkstyle.SeverityLevel
|
||||
*/
|
||||
public final SeverityLevel getSeverityLevel()
|
||||
{
|
||||
return mSeverityLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the severity level. The string should be one of the names
|
||||
* defined in the <code>SeverityLevel</code> class.
|
||||
*
|
||||
* @param aSeverity The new severity level
|
||||
* @see com.puppycrawl.tools.checkstyle.SeverityLevel
|
||||
*/
|
||||
public void setSeverity(String aSeverity)
|
||||
{
|
||||
mSeverityLevel = SeverityLevel.getInstance(aSeverity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the severity level's name.
|
||||
*
|
||||
* @return the check's severity level name.
|
||||
*/
|
||||
public String getSeverity()
|
||||
{
|
||||
return mSeverityLevel.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error message.
|
||||
*
|
||||
|
|
@ -246,7 +282,7 @@ public abstract class Check extends AutomaticBean
|
|||
protected final void log(int aLine, String aKey, Object aArgs[])
|
||||
{
|
||||
mMessages.add(new LocalizedMessage(
|
||||
aLine, getResourceBundle(), aKey, aArgs));
|
||||
aLine, getResourceBundle(), aKey, aArgs, mSeverityLevel));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -347,7 +383,7 @@ public abstract class Check extends AutomaticBean
|
|||
final int col = 1 + Utils.lengthExpandedTabs(
|
||||
getLines()[aLineNo - 1], aColNo, getTabWidth());
|
||||
mMessages.add(new LocalizedMessage(
|
||||
aLineNo, col, getResourceBundle(), aKey, aArgs));
|
||||
aLineNo, col, getResourceBundle(), aKey, aArgs, mSeverityLevel));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
|||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a message that can be localised. The translations come from
|
||||
* message.properties files. The underlying implementation uses
|
||||
|
|
@ -52,6 +53,11 @@ public final class LocalizedMessage
|
|||
/** the column number **/
|
||||
private final int mColNo;
|
||||
|
||||
/** the severity level **/
|
||||
private final SeverityLevel mSeverityLevel;
|
||||
/** the default severity level if one is not specified */
|
||||
private static final SeverityLevel DEFAULT_SEVERITY = SeverityLevel.WARNING;
|
||||
|
||||
/** key for the message format **/
|
||||
private final String mKey;
|
||||
|
||||
|
|
@ -123,6 +129,32 @@ public final class LocalizedMessage
|
|||
mKey = aKey;
|
||||
mArgs = aArgs;
|
||||
mBundle = aBundle;
|
||||
mSeverityLevel = DEFAULT_SEVERITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>LocalizedMessage</code> instance.
|
||||
*
|
||||
* @param aLineNo line number associated with the message
|
||||
* @param aColNo column number associated with the message
|
||||
* @param aBundle resource bundle name
|
||||
* @param aKey the key to locate the translation
|
||||
* @param aArgs arguments for the translation
|
||||
* @param aSeverityLevel severity level for the message
|
||||
*/
|
||||
public LocalizedMessage(int aLineNo,
|
||||
int aColNo,
|
||||
String aBundle,
|
||||
String aKey,
|
||||
Object[] aArgs,
|
||||
SeverityLevel aSeverityLevel)
|
||||
{
|
||||
mLineNo = aLineNo;
|
||||
mColNo = aColNo;
|
||||
mKey = aKey;
|
||||
mArgs = aArgs;
|
||||
mBundle = aBundle;
|
||||
mSeverityLevel = aSeverityLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -140,6 +172,23 @@ public final class LocalizedMessage
|
|||
this(aLineNo, 0, aBundle, aKey, aArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>LocalizedMessage</code> instance. The column number
|
||||
* defaults to 0.
|
||||
*
|
||||
* @param aLineNo line number associated with the message
|
||||
* @param aBundle name of a resource bundle that contains error messages
|
||||
* @param aKey the key to locate the translation
|
||||
* @param aArgs arguments for the translation
|
||||
* @param aSeverityLevel severity level for the message
|
||||
*/
|
||||
public LocalizedMessage(
|
||||
int aLineNo, String aBundle, String aKey, Object[] aArgs,
|
||||
SeverityLevel aSeverityLevel)
|
||||
{
|
||||
this(aLineNo, 0, aBundle, aKey, aArgs, aSeverityLevel);
|
||||
}
|
||||
|
||||
/** @return the translated message **/
|
||||
public String getMessage()
|
||||
{
|
||||
|
|
@ -187,6 +236,12 @@ public final class LocalizedMessage
|
|||
return mColNo;
|
||||
}
|
||||
|
||||
/** @return the severity level **/
|
||||
public SeverityLevel getSeverityLevel()
|
||||
{
|
||||
return mSeverityLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message key to locate the translation, can also be used
|
||||
* in IDE plugins to map error messages to corrective actions.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,184 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// checkstyle: Checks Java source code for adherence to a set of rules.
|
||||
// Copyright (C) 2001-2002 Oliver Burn
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.api;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Severity level for a check violation.
|
||||
* <p>
|
||||
* Each violation of an audit check is assigned one of the severity levels
|
||||
* defined here.
|
||||
*
|
||||
* @author David Schneider
|
||||
*/
|
||||
public final class SeverityLevel implements Comparable, Serializable
|
||||
{
|
||||
/** Numeric value for severity level IGNORE */
|
||||
private static final int SEVERITYCODE_IGNORE = 10;
|
||||
/** Numeric value for severity level INFO */
|
||||
private static final int SEVERITYCODE_INFO = 20;
|
||||
/** Numeric value for severity level WARNING */
|
||||
private static final int SEVERITYCODE_WARNING = 30;
|
||||
/** Numeric value for severity level ERROR */
|
||||
private static final int SEVERITYCODE_ERROR = 40;
|
||||
|
||||
|
||||
/** Name for severity level IGNORE */
|
||||
private static final String SEVERITYNAME_IGNORE = "ignore";
|
||||
/** Name for severity level INFO */
|
||||
private static final String SEVERITYNAME_INFO = "info";
|
||||
/** Name for severity level WARNING */
|
||||
private static final String SEVERITYNAME_WARNING = "warning";
|
||||
/** Name for severity level ERROR */
|
||||
private static final String SEVERITYNAME_ERROR = "error";
|
||||
|
||||
/** nothing scope */
|
||||
public static final SeverityLevel IGNORE =
|
||||
new SeverityLevel(SEVERITYCODE_IGNORE, SEVERITYNAME_IGNORE);
|
||||
|
||||
/** public scope */
|
||||
public static final SeverityLevel INFO =
|
||||
new SeverityLevel(SEVERITYCODE_INFO, SEVERITYNAME_INFO);
|
||||
|
||||
/** protected scope */
|
||||
public static final SeverityLevel WARNING =
|
||||
new SeverityLevel(SEVERITYCODE_WARNING, SEVERITYNAME_WARNING);
|
||||
|
||||
/** package scope */
|
||||
public static final SeverityLevel ERROR =
|
||||
new SeverityLevel(SEVERITYCODE_ERROR, SEVERITYNAME_ERROR);
|
||||
|
||||
/** map from scope names to the respective Scope */
|
||||
private static final Map NAME_TO_SCOPE = new HashMap();
|
||||
static {
|
||||
NAME_TO_SCOPE.put(SEVERITYNAME_IGNORE, IGNORE);
|
||||
NAME_TO_SCOPE.put(SEVERITYNAME_INFO, INFO);
|
||||
NAME_TO_SCOPE.put(SEVERITYNAME_WARNING, WARNING);
|
||||
NAME_TO_SCOPE.put(SEVERITYNAME_ERROR, ERROR);
|
||||
}
|
||||
|
||||
/** the SEVERITYCODE_XYZ value of this severity level. */
|
||||
private final int mCode;
|
||||
|
||||
/** the name of this severity level. */
|
||||
private final String mName;
|
||||
|
||||
/**
|
||||
* @see Object
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "Severity[" + mCode + " (" + mName + ")]";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of this severity level.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Comparable
|
||||
*/
|
||||
public int compareTo(Object aObject)
|
||||
{
|
||||
SeverityLevel severity = (SeverityLevel) aObject;
|
||||
return this.mCode - severity.mCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* The equals method.
|
||||
*
|
||||
* @param aObj Object to compare to.
|
||||
*
|
||||
* @return <code>true</code> means equal, <code>false</code> means
|
||||
* not equal.
|
||||
*/
|
||||
public boolean equals(Object aObj)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if ((aObj instanceof SeverityLevel)
|
||||
&& (((SeverityLevel) aObj).mCode == this.mCode))
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hashCode method.
|
||||
*
|
||||
* @return hash code for the object.
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return mCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SeverityLevel</code> instance.
|
||||
*
|
||||
* @param aCode one of the SEVERITYCODE_XYZ values.
|
||||
* @param aName one of the SEVERITYNAME_XYZ values.
|
||||
*/
|
||||
private SeverityLevel(int aCode, String aName)
|
||||
{
|
||||
mCode = aCode;
|
||||
mName = aName;
|
||||
}
|
||||
|
||||
/**
|
||||
* SeverityLevel factory method.
|
||||
*
|
||||
* @param aSeverityName severity name, such as "ignore", "info", etc.
|
||||
* @return the <code>SeverityLevel</code> associated with
|
||||
* <code>aSeverityName</code>
|
||||
*/
|
||||
public static SeverityLevel getInstance(String aSeverityName)
|
||||
{
|
||||
// canonicalize argument
|
||||
final String severityName = aSeverityName.trim().toLowerCase();
|
||||
|
||||
final SeverityLevel retVal =
|
||||
(SeverityLevel) NAME_TO_SCOPE.get(severityName);
|
||||
if (retVal == null) {
|
||||
throw new IllegalArgumentException(severityName);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that we don't get multiple instances of one SeverityLevel
|
||||
* during deserialization. See Section 3.6 of the Java Object
|
||||
* Serialization Specification for details.
|
||||
*
|
||||
* @return the serialization replacement object
|
||||
*/
|
||||
private Object readResolve()
|
||||
{
|
||||
return getInstance(mName);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,13 +20,13 @@ import junit.framework.TestCase;
|
|||
public class XMLLoggerTest extends TestCase
|
||||
{
|
||||
private ByteArrayOutputStream outStream;
|
||||
|
||||
|
||||
public void setUp()
|
||||
throws Exception
|
||||
{
|
||||
outStream = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
|
||||
public void testEncode()
|
||||
throws IOException
|
||||
{
|
||||
|
|
@ -43,10 +43,10 @@ public class XMLLoggerTest extends TestCase
|
|||
for (int i = 0; i < encodings.length; i++) {
|
||||
final String encoded = logger.encode(encodings[i][0]);
|
||||
assertEquals("\"" + encodings[i][0] + "\"", encodings[i][1], encoded);
|
||||
}
|
||||
}
|
||||
outStream.close();
|
||||
}
|
||||
|
||||
|
||||
public void testIsReference()
|
||||
throws IOException
|
||||
{
|
||||
|
|
@ -71,36 +71,36 @@ public class XMLLoggerTest extends TestCase
|
|||
for (int i = 0; i < noReference.length; i++) {
|
||||
assertFalse("no reference: " + noReference[i],
|
||||
logger.isReference(noReference[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
outStream.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testCloseStream()
|
||||
throws IOException
|
||||
{
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
logger.auditStarted(null);
|
||||
logger.auditFinished(null);
|
||||
final String[] expectedLines = {};
|
||||
verifyLines(expectedLines);
|
||||
}
|
||||
|
||||
|
||||
public void testNoCloseStream()
|
||||
throws IOException
|
||||
{
|
||||
final XMLLogger logger = new XMLLogger(outStream, false);
|
||||
final XMLLogger logger = new XMLLogger(outStream, false);
|
||||
logger.auditStarted(null);
|
||||
logger.auditFinished(null);
|
||||
outStream.close();
|
||||
final String[] expectedLines = {};
|
||||
verifyLines(expectedLines);
|
||||
}
|
||||
|
||||
|
||||
public void testFileStarted()
|
||||
throws IOException
|
||||
{
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
logger.auditStarted(null);
|
||||
final AuditEvent ev = new AuditEvent(this, "Test.java");
|
||||
logger.fileStarted(ev);
|
||||
|
|
@ -108,11 +108,11 @@ public class XMLLoggerTest extends TestCase
|
|||
final String[] expectedLines = {"<file name=\"Test.java\">"};
|
||||
verifyLines(expectedLines);
|
||||
}
|
||||
|
||||
|
||||
public void testFileFinished()
|
||||
throws IOException
|
||||
{
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
logger.auditStarted(null);
|
||||
final AuditEvent ev = new AuditEvent(this, "Test.java");
|
||||
logger.fileFinished(ev);
|
||||
|
|
@ -124,7 +124,7 @@ public class XMLLoggerTest extends TestCase
|
|||
public void testAddError()
|
||||
throws IOException
|
||||
{
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
logger.auditStarted(null);
|
||||
final LocalizedMessage message =
|
||||
new LocalizedMessage( 1, 1, "messages.properties", "key", null);
|
||||
|
|
@ -132,14 +132,14 @@ public class XMLLoggerTest extends TestCase
|
|||
logger.addError(ev);
|
||||
logger.auditFinished(null);
|
||||
final String[] expectedLines =
|
||||
{"<error line=\"1\" column=\"1\" message=\"key\"/>"};
|
||||
{"<error line=\"1\" column=\"1\" severity=\"warning\" message=\"key\"/>"};
|
||||
verifyLines(expectedLines);
|
||||
}
|
||||
|
||||
|
||||
public void testAddException()
|
||||
throws IOException
|
||||
{
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
final XMLLogger logger = new XMLLogger(outStream, true);
|
||||
logger.auditStarted(null);
|
||||
final LocalizedMessage message =
|
||||
new LocalizedMessage( 1, 1, "messages.properties", null, null);
|
||||
|
|
@ -155,7 +155,7 @@ public class XMLLoggerTest extends TestCase
|
|||
};
|
||||
verifyLines(expectedLines);
|
||||
}
|
||||
|
||||
|
||||
private String[] getOutStreamLines()
|
||||
throws IOException
|
||||
{
|
||||
|
|
@ -175,7 +175,7 @@ public class XMLLoggerTest extends TestCase
|
|||
reader.close();
|
||||
return (String[])lineList.toArray(new String[lineList.size()]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verify output lines from auditStart to auditEnd.
|
||||
* Take into consideration checkstyle element (first and last lines).
|
||||
|
|
@ -196,12 +196,12 @@ public class XMLLoggerTest extends TestCase
|
|||
}
|
||||
assertEquals("last line.", "</checkstyle>", lines[lines.length - 1]);
|
||||
}
|
||||
|
||||
|
||||
private class TestThrowable extends Exception
|
||||
{
|
||||
public void printStackTrace(PrintWriter s)
|
||||
{
|
||||
s.print("stackTrace");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue