public class ImportOrderCheck extends AbstractCheck
ImportOrderOption
Properties:
name | Description | type | default value |
---|---|---|---|
option | policy on the relative order between regular imports and static imports | ImportOrderOption | under |
groups | list of imports groups (every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/) | list of strings | empty list |
ordered | whether imports within group should be sorted | Boolean | true |
separated | whether imports groups should be separated by, at least, one blank line and aren't separated internally | Boolean | false |
caseSensitive | whether string comparison should be case sensitive or not. Case sensitive sorting is in ASCII sort order | Boolean | true |
sortStaticImportsAlphabetically | whether static imports grouped by top or bottom option are sorted alphabetically or not | Boolean | false |
useContainerOrderingForStatic | whether to use container ordering (Eclipse IDE term) for static imports or not | Boolean | false |
Example:
To configure the check so that it matches default Eclipse formatter configuration (tested on Kepler, Luna and Mars):
<module name="ImportOrder"> <property name="groups" value="/^javax?\./,org"/> <property name="ordered" value="true"/> <property name="separated" value="true"/> <property name="option" value="above"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
To configure the check so that it matches default IntelliJ IDEA formatter configuration (tested on v14):
Note: "separated" option is disabled because IDEA default has blank line between "java" and static imports, and no blank line between "javax" and "java"
<module name="ImportOrder"> <property name="groups" value="*,javax,java"/> <property name="ordered" value="true"/> <property name="separated" value="false"/> <property name="option" value="bottom"/> <property name="sortStaticImportsAlphabetically" value="true"/> </module>
To configure the check so that it matches default NetBeans formatter configuration (tested on v8):
<module name="ImportOrder"> <property name="option" value="inflow"/> </module>
Group descriptions enclosed in slashes are interpreted as regular expressions. If multiple groups match, the one matching a longer substring of the imported name will take precedence, with ties broken first in favor of earlier matches and finally in favor of the first matching group.
There is always a wildcard group to which everything not in a named group
belongs. If an import does not match a named group, the group belongs to
this wildcard group. The wildcard group position can be specified using the
*
character.
Check also has on option making it more flexible:
sortStaticImportsAlphabetically - sets whether static imports grouped by
top or bottom option should be sorted alphabetically or
not, default value is false. It is applied to static imports grouped
with top or bottom options.
This option is helping in reconciling of this Check and other tools like
Eclipse's Organize Imports feature.
To configure the Check allows static imports grouped to the top being sorted alphabetically:
import static java.lang.Math.abs;
import static org.abego.treelayout.Configuration.AlignmentInLevel; // OK, alphabetical order
import org.abego.*;
import java.util.Set;
public class SomeClass { ... }
Modifier and Type | Field and Description |
---|---|
private boolean |
beforeFirstImport
Whether there was any imports.
|
private boolean |
caseSensitive
Should comparison be case sensitive.
|
private static java.util.regex.Pattern[] |
EMPTY_PATTERN_ARRAY
Empty array of pattern type needed to initialize check.
|
private java.util.regex.Pattern[] |
groups
List of import groups specified by the user.
|
private int |
lastGroup
Last imported group.
|
private java.lang.String |
lastImport
Name of last import.
|
private int |
lastImportLine
Line number of last import.
|
private boolean |
lastImportStatic
If last import was static.
|
static java.lang.String |
MSG_ORDERING
A key is pointing to the warning message text in "messages.properties"
file.
|
static java.lang.String |
MSG_SEPARATED_IN_GROUP
A key is pointing to the warning message text in "messages.properties"
file.
|
static java.lang.String |
MSG_SEPARATION
A key is pointing to the warning message text in "messages.properties"
file.
|
private ImportOrderOption |
option
The policy to enforce.
|
private boolean |
ordered
Require imports in group.
|
private boolean |
separated
Require imports in group be separated.
|
private boolean |
sortStaticImportsAlphabetically
Whether static imports should be sorted alphabetically or not.
|
private boolean |
useContainerOrderingForStatic
Whether to use container ordering (Eclipse IDE term) for static imports or not.
|
private static java.lang.String |
WILDCARD_GROUP_NAME
The special wildcard that catches all remaining groups.
|
Constructor and Description |
---|
ImportOrderCheck() |
Modifier and Type | Method and Description |
---|---|
void |
beginTree(DetailAST rootAST)
Called before the starting to process a tree.
|
private boolean |
checkSeparatorInGroup(int groupIdx,
boolean isStatic,
int line)
Checks whether imports group separated internally.
|
private static int |
compare(java.lang.String string1,
java.lang.String string2,
boolean caseSensitive)
Compares two strings.
|
private static int |
compareContainerOrder(java.lang.String importName1,
java.lang.String importName2,
boolean caseSensitive)
Compares two import strings.
|
private void |
doVisitToken(FullIdent ident,
boolean isStatic,
boolean previous)
Shares processing...
|
private void |
doVisitTokenInSameGroup(boolean isStatic,
boolean previous,
java.lang.String name,
int line)
Shares processing...
|
int[] |
getAcceptableTokens()
The configurable token set.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private int |
getGroupNumber(java.lang.String name)
Finds out what group the specified import belongs to.
|
private static java.lang.String |
getImportContainer(java.lang.String qualifiedImportName)
Extracts import container name from fully qualified import name.
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private boolean |
isAlphabeticallySortableStaticImport(boolean isStatic)
Checks whether static imports grouped by top or bottom option
are sorted alphabetically or not.
|
private boolean |
isWrongOrder(java.lang.String name,
boolean isStatic)
Checks whether import name is in wrong order.
|
void |
setCaseSensitive(boolean caseSensitive)
Sets whether string comparison should be case sensitive or not.
|
void |
setGroups(java.lang.String... packageGroups)
Sets the list of package groups and the order they should occur in the
file.
|
void |
setOption(java.lang.String optionStr)
Set the option to enforce.
|
void |
setOrdered(boolean ordered)
Sets whether or not imports should be ordered within any one group of
imports.
|
void |
setSeparated(boolean separated)
Sets whether or not groups of imports must be separated from one another
by at least one blank line.
|
void |
setSortStaticImportsAlphabetically(boolean sortAlphabetically)
Sets whether static imports (when grouped using 'top' and 'bottom' option)
are sorted alphabetically or according to the package groupings.
|
void |
setUseContainerOrderingForStatic(boolean useContainerOrdering)
Sets whether to use container ordering (Eclipse IDE term) for static imports or not.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
destroy, finishTree, getClassLoader, getFileContents, getLine, getLines, getTabWidth, getTokenNames, init, isCommentNodesRequired, leaveToken, log, log, setClassLoader, setFileContents, setMessages, setTabWidth, setTokens
getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, log, setId, setSeverity
configure, contextualize, finishLocalSetup, getConfiguration, setupChild
public static final java.lang.String MSG_SEPARATION
public static final java.lang.String MSG_ORDERING
public static final java.lang.String MSG_SEPARATED_IN_GROUP
private static final java.lang.String WILDCARD_GROUP_NAME
private static final java.util.regex.Pattern[] EMPTY_PATTERN_ARRAY
private java.util.regex.Pattern[] groups
private boolean separated
private boolean ordered
private boolean caseSensitive
private int lastGroup
private int lastImportLine
private java.lang.String lastImport
private boolean lastImportStatic
private boolean beforeFirstImport
private boolean sortStaticImportsAlphabetically
private boolean useContainerOrderingForStatic
private ImportOrderOption option
public void setOption(java.lang.String optionStr)
optionStr
- string to decode option fromjava.lang.IllegalArgumentException
- if unable to decodepublic void setGroups(java.lang.String... packageGroups)
packageGroups
- a comma-separated list of package names/prefixes.public void setOrdered(boolean ordered)
ordered
- whether lexicographic ordering of imports within a group
required or not.public void setSeparated(boolean separated)
separated
- whether groups should be separated by oen blank line.public void setCaseSensitive(boolean caseSensitive)
caseSensitive
- whether string comparison should be case sensitive.public void setSortStaticImportsAlphabetically(boolean sortAlphabetically)
sortAlphabetically
- true or false.public void setUseContainerOrderingForStatic(boolean useContainerOrdering)
useContainerOrdering
- whether to use container ordering for static imports or not.public int[] getDefaultTokens()
AbstractCheck
getDefaultTokens
in class AbstractCheck
TokenTypes
public int[] getAcceptableTokens()
AbstractCheck
getAcceptableTokens
in class AbstractCheck
TokenTypes
public int[] getRequiredTokens()
AbstractCheck
getRequiredTokens
in class AbstractCheck
TokenTypes
public void beginTree(DetailAST rootAST)
AbstractCheck
beginTree
in class AbstractCheck
rootAST
- the root of the treepublic void visitToken(DetailAST ast)
AbstractCheck
visitToken
in class AbstractCheck
ast
- the token to processprivate void doVisitToken(FullIdent ident, boolean isStatic, boolean previous)
ident
- the import to process.isStatic
- whether the token is static or not.previous
- previous non-static but current is static (above), or
previous static but current is non-static (under).private boolean checkSeparatorInGroup(int groupIdx, boolean isStatic, int line)
groupIdx
- group number.isStatic
- whether the token is static or not.line
- the line of the current import.private boolean isAlphabeticallySortableStaticImport(boolean isStatic)
isStatic
- if current import is static.private void doVisitTokenInSameGroup(boolean isStatic, boolean previous, java.lang.String name, int line)
isStatic
- whether the token is static or not.previous
- previous non-static but current is static (above), or
previous static but current is non-static (under).name
- the name of the current import.line
- the line of the current import.private boolean isWrongOrder(java.lang.String name, boolean isStatic)
name
- import name.isStatic
- whether it is a static import name.private static int compareContainerOrder(java.lang.String importName1, java.lang.String importName2, boolean caseSensitive)
import static HttpConstants.COLON => HttpConstants import static HttpHeaders.addHeader => HttpHeaders import static HttpHeaders.setHeader => HttpHeaders import static HttpHeaders.Names.DATE => HttpHeaders.Names
According to this logic, HttpHeaders.Names would come after HttpHeaders. For more details, see static imports comparison method in Eclipse.
importName1
- first import name.importName2
- second import name.caseSensitive
- whether the comparison of fully qualified import names is case
sensitive.0
if str1 is equal to str2; a value
less than 0
if str is less than the str2 (container order
or lexicographical); and a value greater than 0
if str1 is greater than str2
(container order or lexicographically).private static java.lang.String getImportContainer(java.lang.String qualifiedImportName)
import static HttpConstants.COLON => HttpConstants import static HttpHeaders.addHeader => HttpHeaders import static HttpHeaders.setHeader => HttpHeaders import static HttpHeaders.Names.DATE => HttpHeaders.Names
qualifiedImportName
- fully qualified import name.private int getGroupNumber(java.lang.String name)
name
- the import name to find.private static int compare(java.lang.String string1, java.lang.String string2, boolean caseSensitive)
string1
- the first string.string2
- the second string.caseSensitive
- whether the comparison is case sensitive.0
if string1 is equal to string2; a value
less than 0
if string1 is lexicographically less
than the string2; and a value greater than 0
if
string1 is lexicographically greater than string2.