Patch from David Schneider to add Severity to logged messages.

This commit is contained in:
Oliver Burn 2003-03-11 06:56:45 +00:00
parent 5d4dd44322
commit 53197d9be9
7 changed files with 318 additions and 32 deletions

View File

@ -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()
{

View File

@ -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());

View File

@ -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()) + "\"/>");
}

View File

@ -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));
}

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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");
}
}
}
}