improved resource bundle handling:
- plugins can use their own bundle (location determined automatically) - return the message key if ResourceBundle is not available - added log helper methods in Check.java
This commit is contained in:
parent
18ce1a9f66
commit
4880b50a3a
|
|
@ -224,21 +224,21 @@ public class Checker
|
|||
}
|
||||
catch (FileNotFoundException fnfe) {
|
||||
errors = new LocalizedMessage[] {
|
||||
new LocalizedMessage(0, "general.fileNotFound", null)};
|
||||
new LocalizedMessage(0, "general.fileNotFound", null, null)};
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
errors = new LocalizedMessage[] {
|
||||
new LocalizedMessage(0, "general.exception",
|
||||
new LocalizedMessage(0, "general.exception", null,
|
||||
new String[] {ioe.getMessage()})};
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
errors = new LocalizedMessage[] {
|
||||
new LocalizedMessage(0, "general.exception",
|
||||
new LocalizedMessage(0, "general.exception", null,
|
||||
new String[] {re.getMessage()})};
|
||||
}
|
||||
catch (TokenStreamException te) {
|
||||
errors = new LocalizedMessage[] {
|
||||
new LocalizedMessage(0, "general.exception",
|
||||
new LocalizedMessage(0, "general.exception", null,
|
||||
new String[] {te.getMessage()})};
|
||||
}
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ public class Checker
|
|||
fireFileStarted(docFile);
|
||||
if (!packageDoc.exists()) {
|
||||
final LocalizedMessage error =
|
||||
new LocalizedMessage(0, "javadoc.packageHtml", null);
|
||||
new LocalizedMessage(0, "javadoc.packageHtml", null, null);
|
||||
fireErrors(docFile, new LocalizedMessage[]{error});
|
||||
packageHtmlErrors++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ import java.util.Map;
|
|||
*/
|
||||
public abstract class Check
|
||||
{
|
||||
/** resuable constant for message formating */
|
||||
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
|
||||
|
||||
/** name to store lines under */
|
||||
private static final String LINES_ATTRIBUTE = "lines";
|
||||
/** name to store filename under */
|
||||
|
|
@ -170,7 +173,7 @@ public abstract class Check
|
|||
* Set the lines associated with the tree.
|
||||
* @param aLines the file contents
|
||||
*/
|
||||
public void setLines(String[] aLines)
|
||||
public final void setLines(String[] aLines)
|
||||
{
|
||||
getTreeContext().put(LINES_ATTRIBUTE, aLines);
|
||||
}
|
||||
|
|
@ -179,7 +182,7 @@ public abstract class Check
|
|||
* Returns the lines associated with the tree.
|
||||
* @return the file contents
|
||||
*/
|
||||
public String[] getLines()
|
||||
protected final String[] getLines()
|
||||
{
|
||||
return (String[]) getTreeContext().get(LINES_ATTRIBUTE);
|
||||
}
|
||||
|
|
@ -188,7 +191,7 @@ public abstract class Check
|
|||
* Set the name of the file associated with the tree.
|
||||
* @param aFilename the file name
|
||||
*/
|
||||
public void setFilename(String aFilename)
|
||||
public final void setFilename(String aFilename)
|
||||
{
|
||||
getTreeContext().put(FILENAME_ATTRIBUTE, aFilename);
|
||||
}
|
||||
|
|
@ -197,15 +200,120 @@ public abstract class Check
|
|||
* Returns the filename associated with the tree.
|
||||
* @return the file name
|
||||
*/
|
||||
public String getFilename()
|
||||
protected final String getFilename()
|
||||
{
|
||||
return (String) getTreeContext().get(FILENAME_ATTRIBUTE);
|
||||
}
|
||||
|
||||
/** @see needs to be fixed */
|
||||
public void log(int aLine, String aMessage)
|
||||
/**
|
||||
* Log an error message.
|
||||
*
|
||||
* @param aLine the line number where the error was found
|
||||
* @param aKey the message that describes the error
|
||||
*/
|
||||
protected final void log(int aLine, String aKey)
|
||||
{
|
||||
final String fname = (String) getTreeContext().get(FILENAME_ATTRIBUTE);
|
||||
System.out.println(fname + ":" + aLine + ": " + aMessage);
|
||||
log(aLine, aKey, EMPTY_OBJECT_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error message.
|
||||
*
|
||||
* @param aLine the line number where the error was found
|
||||
* @param aKey the message that describes the error
|
||||
* @param aArgs the details of the message
|
||||
*
|
||||
* @see java.text.MessageFormat
|
||||
*/
|
||||
protected final void log(int aLine, String aKey, Object aArgs[])
|
||||
{
|
||||
log(aLine, 0, aKey, aArgs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to log a LocalizedMessage. Column defaults to 0.
|
||||
*
|
||||
* @param aLineNo line number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
*/
|
||||
public void log(int aLineNo, String aKey, Object aArg0)
|
||||
{
|
||||
log(aLineNo, aKey, new Object[] {aArg0});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to log a LocalizedMessage. Column defaults to 0.
|
||||
*
|
||||
* @param aLineNo line number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
* @param aArg1 second argument
|
||||
*/
|
||||
public void log(int aLineNo, String aKey, Object aArg0, Object aArg1)
|
||||
{
|
||||
log(aLineNo, aKey, new Object[] {aArg0, aArg1});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to log a LocalizedMessage. Column defaults to 0.
|
||||
*
|
||||
* @param aLineNo line number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
* @param aArg1 second argument
|
||||
* @param aArg2 third argument
|
||||
*/
|
||||
public void log(int aLineNo, String aKey,
|
||||
Object aArg0, Object aArg1, Object aArg2)
|
||||
{
|
||||
log(aLineNo, aKey, new Object[] {aArg0, aArg1, aArg2});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to log a LocalizedMessage.
|
||||
*
|
||||
* @param aLineNo line number to associate with the message
|
||||
* @param aColNo column number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArgs arguments for message
|
||||
*/
|
||||
public void log(int aLineNo, int aColNo, String aKey, Object[] aArgs)
|
||||
{
|
||||
final String fname = getFilename();
|
||||
System.out.println(fname + ":" + aLineNo + ": " + aKey);
|
||||
|
||||
final int col = aColNo + 1;
|
||||
// final int col = 1 + Utils.lengthExpandedTabs(
|
||||
// mLines[aLineNo - 1], aColNo, mTabWidth);
|
||||
mMessages.add(new LocalizedMessage(
|
||||
aLineNo, col, getResourceBundle(), aKey, aArgs));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: Should this method be protected or should we keep the api simple?
|
||||
* Returns the name of a a resource bundle that contains the messages
|
||||
* used by this check.
|
||||
*
|
||||
* The default implementation expects the resource files to be named
|
||||
* messages.properties, messages_de.properties, etc. The file should
|
||||
* be placed in the same package as the Check implementation.
|
||||
*
|
||||
* Example: If you write com/foo/MyCoolCheck, create resource files
|
||||
* com/foo/messages.properties, com/foo/messages_de.properties, etc.
|
||||
*
|
||||
* @return name of a resource bundle that contains the messages
|
||||
* used by this check
|
||||
*/
|
||||
private String getResourceBundle()
|
||||
{
|
||||
// PERF: check perf impact, maybe cache result
|
||||
final String className = this.getClass().getName();
|
||||
final String packageName =
|
||||
className.substring(className.lastIndexOf('.') + 1);
|
||||
return packageName + "." + "messages";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,13 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.api;
|
||||
|
||||
// TODO: check that this class is in the right package
|
||||
// as soon as architecture has settled. At the time of writing
|
||||
// this class is not necessary as a part of the public api
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Locale;
|
||||
import java.util.MissingResourceException;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
|
|
@ -33,10 +38,6 @@ import java.text.MessageFormat;
|
|||
public class LocalizedMessage
|
||||
implements Comparable
|
||||
{
|
||||
/** name of the resource bundle to get messages from **/
|
||||
private static final String MESSAGE_BUNDLE =
|
||||
"com.puppycrawl.tools.checkstyle.messages";
|
||||
|
||||
/** the locale to localise messages to **/
|
||||
private static Locale sLocale = Locale.getDefault();
|
||||
|
||||
|
|
@ -51,16 +52,22 @@ public class LocalizedMessage
|
|||
/** arguments for MessageFormat **/
|
||||
private final Object[] mArgs;
|
||||
|
||||
/** name of the resource bundle to get messages from **/
|
||||
private final String mBundle;
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public LocalizedMessage(int aLineNo,
|
||||
int aColNo,
|
||||
String aBundle,
|
||||
String aKey,
|
||||
Object[] aArgs)
|
||||
{
|
||||
|
|
@ -68,6 +75,7 @@ public class LocalizedMessage
|
|||
mColNo = aColNo;
|
||||
mKey = aKey;
|
||||
mArgs = aArgs;
|
||||
mBundle = aBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -75,25 +83,36 @@ public class LocalizedMessage
|
|||
* 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
|
||||
*/
|
||||
public LocalizedMessage(int aLineNo, String aKey, Object[] aArgs)
|
||||
public LocalizedMessage(
|
||||
int aLineNo, String aBundle, String aKey, Object[] aArgs)
|
||||
{
|
||||
this(aLineNo, 0, aKey, aArgs);
|
||||
this(aLineNo, 0, aBundle, aKey, aArgs);
|
||||
}
|
||||
|
||||
/** @return the translated message **/
|
||||
public String getMessage()
|
||||
{
|
||||
// Very simple approach - wait for performance problems.
|
||||
// Important to use the default class loader, and not the one in the
|
||||
// Configuration object. This is because the class loader in the
|
||||
// Configuration is specified by the user for resolving custom classes.
|
||||
final ResourceBundle bundle =
|
||||
ResourceBundle.getBundle(MESSAGE_BUNDLE, sLocale);
|
||||
final String pattern = bundle.getString(mKey);
|
||||
return MessageFormat.format(pattern, mArgs);
|
||||
try {
|
||||
// PERF: Very simple approach - wait for performance problems.
|
||||
// Important to use the default class loader, and not the one in the
|
||||
// Configuration object. This is because the class loader in the
|
||||
// Configuration is specified by the user for resolving custom
|
||||
// classes.
|
||||
final ResourceBundle bundle =
|
||||
ResourceBundle.getBundle(mBundle, sLocale);
|
||||
final String pattern = bundle.getString(mKey);
|
||||
return MessageFormat.format(pattern, mArgs);
|
||||
}
|
||||
catch (MissingResourceException ex) {
|
||||
// If the Check author didn't provide i18n resource bundles
|
||||
// and logs error messages directly, this will return
|
||||
// the author's original message
|
||||
return MessageFormat.format(mKey, mArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/** @return the line number **/
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.api;
|
||||
|
||||
// TODO: check that this class is in the right package
|
||||
// as soon as architecture has settled. At the time of writing
|
||||
// this class is not necessary as a part of the public api
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
|
@ -34,6 +38,8 @@ public class LocalizedMessages
|
|||
private final int mTabWidth;
|
||||
/** the lines of the file being checked **/
|
||||
private String[] mLines;
|
||||
private static final String OLD_BUNDLE =
|
||||
"com.puppycrawl.tools.checkstyle.messages";
|
||||
|
||||
/**
|
||||
* Creates a new <code>LocalizedMessages</code> instance.
|
||||
|
|
@ -75,16 +81,21 @@ public class LocalizedMessages
|
|||
mMessages.add(aMsg);
|
||||
}
|
||||
|
||||
// TODO: remove the add() methods below and the OLD_BUNDLE constant
|
||||
// this has to wait until they are not referenced by Verifier any more
|
||||
|
||||
/**
|
||||
* Helper method to log a LocalizedMessage. Column defaults to 0.
|
||||
*
|
||||
* @param aLineNo line number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArgs arguments for message
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, String aKey, Object[] aArgs)
|
||||
{
|
||||
add(new LocalizedMessage(aLineNo, 0, aKey, aArgs));
|
||||
add(new LocalizedMessage(aLineNo, 0, OLD_BUNDLE, aKey, aArgs));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -92,6 +103,8 @@ public class LocalizedMessages
|
|||
*
|
||||
* @param aLineNo line number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, String aKey)
|
||||
{
|
||||
|
|
@ -104,6 +117,8 @@ public class LocalizedMessages
|
|||
* @param aLineNo line number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, String aKey, Object aArg0)
|
||||
{
|
||||
|
|
@ -117,6 +132,8 @@ public class LocalizedMessages
|
|||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
* @param aArg1 second argument
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, String aKey, Object aArg0, Object aArg1)
|
||||
{
|
||||
|
|
@ -131,6 +148,8 @@ public class LocalizedMessages
|
|||
* @param aArg0 first argument
|
||||
* @param aArg1 second argument
|
||||
* @param aArg2 third argument
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, String aKey,
|
||||
Object aArg0, Object aArg1, Object aArg2)
|
||||
|
|
@ -145,12 +164,15 @@ public class LocalizedMessages
|
|||
* @param aColNo column number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArgs arguments for message
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, int aColNo, String aKey, Object[] aArgs)
|
||||
{
|
||||
final int col = 1 + Utils.lengthExpandedTabs(
|
||||
mLines[aLineNo - 1], aColNo, mTabWidth);
|
||||
mMessages.add(new LocalizedMessage(aLineNo, col, aKey, aArgs));
|
||||
mMessages.add(
|
||||
new LocalizedMessage(aLineNo, col, OLD_BUNDLE, aKey, aArgs));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,6 +181,8 @@ public class LocalizedMessages
|
|||
* @param aLineNo line number to associate with the message
|
||||
* @param aColNo column number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, int aColNo, String aKey)
|
||||
{
|
||||
|
|
@ -172,6 +196,8 @@ public class LocalizedMessages
|
|||
* @param aColNo column number to associate with the message
|
||||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, int aColNo, String aKey, Object aArg0)
|
||||
{
|
||||
|
|
@ -186,6 +212,8 @@ public class LocalizedMessages
|
|||
* @param aKey key to locale message format
|
||||
* @param aArg0 first argument
|
||||
* @param aArg1 second argument
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
public void add(int aLineNo, int aColNo, String aKey,
|
||||
Object aArg0, Object aArg1)
|
||||
|
|
@ -202,6 +230,8 @@ public class LocalizedMessages
|
|||
* @param aArg0 first argument
|
||||
* @param aArg1 second argument
|
||||
* @param aArg2 third argument
|
||||
*
|
||||
* @deprecated replaced by Check.log()
|
||||
*/
|
||||
void add(int aLineNo, int aColNo, String aKey,
|
||||
Object aArg0, Object aArg1, Object aArg2)
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ tokens {
|
|||
STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL;
|
||||
}
|
||||
|
||||
|
||||
// Compilation Unit: In Java, this is a single file. This is the start
|
||||
// rule for this parser
|
||||
compilationUnit
|
||||
|
|
@ -927,6 +928,24 @@ options {
|
|||
codeGenBitsetTestThreshold=20;
|
||||
}
|
||||
|
||||
// JavaLexer verbatim source code
|
||||
{
|
||||
|
||||
// explicitly set tab width to 1 (default in ANTLR 2.7.1)
|
||||
// in ANTLR 2.7.2a2 the default has changed from 1 to 8
|
||||
public void tab()
|
||||
{
|
||||
setColumn( getColumn() + 1 );
|
||||
}
|
||||
|
||||
private CommentManager mCommentManager = null;
|
||||
|
||||
void setCommentManager(CommentManager aCommentManager)
|
||||
{
|
||||
mCommentManager = aCommentManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// OPERATORS
|
||||
|
|
@ -995,14 +1014,18 @@ WS : ( ' '
|
|||
|
||||
// Single-line comments
|
||||
SL_COMMENT
|
||||
: "//"
|
||||
: "//" { mCommentManager.reportCPPComment(getLine(), getColumn() - 3); }
|
||||
(~('\n'|'\r'))* ('\n'|'\r'('\n')?)
|
||||
{$setType(Token.SKIP); newline();}
|
||||
;
|
||||
|
||||
// multiple-line comments
|
||||
ML_COMMENT
|
||||
: "/*"
|
||||
{
|
||||
int startLine;
|
||||
int startCol;
|
||||
}
|
||||
: "/*" { startLine = getLine(); startCol = getColumn() - 3; }
|
||||
( /* '\r' '\n' can be matched in one alternative or by matching
|
||||
'\r' in one iteration and '\n' in another. I am trying to
|
||||
handle any flavor of newline that comes in, but the language
|
||||
|
|
@ -1021,7 +1044,11 @@ ML_COMMENT
|
|||
| ~('*'|'\n'|'\r')
|
||||
)*
|
||||
"*/"
|
||||
{$setType(Token.SKIP);}
|
||||
{
|
||||
mCommentManager.reportCComment(startLine, startCol,
|
||||
getLine(), getColumn() - 2);
|
||||
$setType(Token.SKIP);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue