Class ImportOrderCheck
- java.lang.Object
-
- com.puppycrawl.tools.checkstyle.api.AutomaticBean
-
- com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
-
- com.puppycrawl.tools.checkstyle.api.AbstractCheck
-
- com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck
-
- All Implemented Interfaces:
Configurable
,Contextualizable
public class ImportOrderCheck extends AbstractCheck
- groups imports: ensures that groups of imports come in a specific order (e.g., java. comes first, javax. comes second, then everything else)
- adds a separation between groups : ensures that a blank line sit between each group
- import groups aren't separated internally: ensures that each group aren't separated internally by blank line or comment
- sorts imports inside each group: ensures that imports within each group are in lexicographic order
- sorts according to case: ensures that the comparison between import is case sensitive
- groups static imports: ensures that static imports are at the top (or the
bottom) of all the imports, or above (or under) each group, or are treated
like non static imports (@see
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):
- group of static imports is on the top
- groups of non-static imports: "java" then "javax" packages first, then "org" and then all other imports
- imports will be sorted in the groups
- groups are separated by, at least, one blank line and aren't separated internally
<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):
- group of static imports is on the bottom
- groups of non-static imports: all imports except of "javax" and "java", then "javax" and "java"
- imports will be sorted in the groups
- groups are separated by, at least, one blank line and aren't separated internally
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):
- groups of non-static imports are not defined, all imports will be sorted as a one group
- static imports are not separated, they will be sorted along with other imports
<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 { ... }
-
-
Field Summary
Fields Modifier and Type Field 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 Summary
Constructors Constructor Description ImportOrderCheck()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method 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.-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck
destroy, finishTree, getClassLoader, getFileContents, getLine, getLines, getTabWidth, getTokenNames, init, isCommentNodesRequired, leaveToken, log, log, setClassLoader, setFileContents, setMessages, setTabWidth, setTokens
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, log, setId, setSeverity
-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean
configure, contextualize, finishLocalSetup, getConfiguration, setupChild
-
-
-
-
Field Detail
-
MSG_SEPARATION
public static final java.lang.String MSG_SEPARATION
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_ORDERING
public static final java.lang.String MSG_ORDERING
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_SEPARATED_IN_GROUP
public static final java.lang.String MSG_SEPARATED_IN_GROUP
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
WILDCARD_GROUP_NAME
private static final java.lang.String WILDCARD_GROUP_NAME
The special wildcard that catches all remaining groups.- See Also:
- Constant Field Values
-
EMPTY_PATTERN_ARRAY
private static final java.util.regex.Pattern[] EMPTY_PATTERN_ARRAY
Empty array of pattern type needed to initialize check.
-
groups
private java.util.regex.Pattern[] groups
List of import groups specified by the user.
-
separated
private boolean separated
Require imports in group be separated.
-
ordered
private boolean ordered
Require imports in group.
-
caseSensitive
private boolean caseSensitive
Should comparison be case sensitive.
-
lastGroup
private int lastGroup
Last imported group.
-
lastImportLine
private int lastImportLine
Line number of last import.
-
lastImport
private java.lang.String lastImport
Name of last import.
-
lastImportStatic
private boolean lastImportStatic
If last import was static.
-
beforeFirstImport
private boolean beforeFirstImport
Whether there was any imports.
-
sortStaticImportsAlphabetically
private boolean sortStaticImportsAlphabetically
Whether static imports should be sorted alphabetically or not.
-
useContainerOrderingForStatic
private boolean useContainerOrderingForStatic
Whether to use container ordering (Eclipse IDE term) for static imports or not.
-
option
private ImportOrderOption option
The policy to enforce.
-
-
Method Detail
-
setOption
public void setOption(java.lang.String optionStr)
Set the option to enforce.- Parameters:
optionStr
- string to decode option from- Throws:
java.lang.IllegalArgumentException
- if unable to decode
-
setGroups
public void setGroups(java.lang.String... packageGroups)
Sets the list of package groups and the order they should occur in the file.- Parameters:
packageGroups
- a comma-separated list of package names/prefixes.
-
setOrdered
public void setOrdered(boolean ordered)
Sets whether or not imports should be ordered within any one group of imports.- Parameters:
ordered
- whether lexicographic ordering of imports within a group required or not.
-
setSeparated
public void setSeparated(boolean separated)
Sets whether or not groups of imports must be separated from one another by at least one blank line.- Parameters:
separated
- whether groups should be separated by oen blank line.
-
setCaseSensitive
public void setCaseSensitive(boolean caseSensitive)
Sets whether string comparison should be case sensitive or not.- Parameters:
caseSensitive
- whether string comparison should be case sensitive.
-
setSortStaticImportsAlphabetically
public void setSortStaticImportsAlphabetically(boolean sortAlphabetically)
Sets whether static imports (when grouped using 'top' and 'bottom' option) are sorted alphabetically or according to the package groupings.- Parameters:
sortAlphabetically
- true or false.
-
setUseContainerOrderingForStatic
public void setUseContainerOrderingForStatic(boolean useContainerOrdering)
Sets whether to use container ordering (Eclipse IDE term) for static imports or not.- Parameters:
useContainerOrdering
- whether to use container ordering for static imports or not.
-
getDefaultTokens
public int[] getDefaultTokens()
Description copied from class:AbstractCheck
Returns the default token a check is interested in. Only used if the configuration for a check does not define the tokens.- Specified by:
getDefaultTokens
in classAbstractCheck
- Returns:
- the default tokens
- See Also:
TokenTypes
-
getAcceptableTokens
public int[] getAcceptableTokens()
Description copied from class:AbstractCheck
The configurable token set. Used to protect Checks against malicious users who specify an unacceptable token set in the configuration file. The default implementation returns the check's default tokens.- Specified by:
getAcceptableTokens
in classAbstractCheck
- Returns:
- the token set this check is designed for.
- See Also:
TokenTypes
-
getRequiredTokens
public int[] getRequiredTokens()
Description copied from class:AbstractCheck
The tokens that this check must be registered for.- Specified by:
getRequiredTokens
in classAbstractCheck
- Returns:
- the token set this must be registered for.
- See Also:
TokenTypes
-
beginTree
public void beginTree(DetailAST rootAST)
Description copied from class:AbstractCheck
Called before the starting to process a tree. Ideal place to initialize information that is to be collected whilst processing a tree.- Overrides:
beginTree
in classAbstractCheck
- Parameters:
rootAST
- the root of the tree
-
visitToken
public void visitToken(DetailAST ast)
Description copied from class:AbstractCheck
Called to process a token.- Overrides:
visitToken
in classAbstractCheck
- Parameters:
ast
- the token to process
-
doVisitToken
private void doVisitToken(FullIdent ident, boolean isStatic, boolean previous)
Shares processing...- Parameters:
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).
-
checkSeparatorInGroup
private boolean checkSeparatorInGroup(int groupIdx, boolean isStatic, int line)
Checks whether imports group separated internally.- Parameters:
groupIdx
- group number.isStatic
- whether the token is static or not.line
- the line of the current import.- Returns:
- true if imports group are separated internally.
-
isAlphabeticallySortableStaticImport
private boolean isAlphabeticallySortableStaticImport(boolean isStatic)
Checks whether static imports grouped by top or bottom option are sorted alphabetically or not.- Parameters:
isStatic
- if current import is static.- Returns:
- true if static imports should be sorted alphabetically.
-
doVisitTokenInSameGroup
private void doVisitTokenInSameGroup(boolean isStatic, boolean previous, java.lang.String name, int line)
Shares processing...- Parameters:
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.
-
isWrongOrder
private boolean isWrongOrder(java.lang.String name, boolean isStatic)
Checks whether import name is in wrong order.- Parameters:
name
- import name.isStatic
- whether it is a static import name.- Returns:
- true if import name is in wrong order.
-
compareContainerOrder
private static int compareContainerOrder(java.lang.String importName1, java.lang.String importName2, boolean caseSensitive)
Compares two import strings. We first compare the container of the static import, container being the type enclosing the static element being imported. When this returns 0, we compare the qualified import name. For e.g. this is what is considered to be container names: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.
- Parameters:
importName1
- first import name.importName2
- second import name.caseSensitive
- whether the comparison of fully qualified import names is case sensitive.- Returns:
- the value
0
if str1 is equal to str2; a value less than0
if str is less than the str2 (container order or lexicographical); and a value greater than0
if str1 is greater than str2 (container order or lexicographically).
-
getImportContainer
private static java.lang.String getImportContainer(java.lang.String qualifiedImportName)
Extracts import container name from fully qualified import name. An import container name is the type which encloses the static element being imported. For example, HttpConstants, HttpHeaders, HttpHeaders.Names are import container names:import static HttpConstants.COLON => HttpConstants import static HttpHeaders.addHeader => HttpHeaders import static HttpHeaders.setHeader => HttpHeaders import static HttpHeaders.Names.DATE => HttpHeaders.Names
- Parameters:
qualifiedImportName
- fully qualified import name.- Returns:
- import container name.
-
getGroupNumber
private int getGroupNumber(java.lang.String name)
Finds out what group the specified import belongs to.- Parameters:
name
- the import name to find.- Returns:
- group number for given import name.
-
compare
private static int compare(java.lang.String string1, java.lang.String string2, boolean caseSensitive)
Compares two strings.- Parameters:
string1
- the first string.string2
- the second string.caseSensitive
- whether the comparison is case sensitive.- Returns:
- the value
0
if string1 is equal to string2; a value less than0
if string1 is lexicographically less than the string2; and a value greater than0
if string1 is lexicographically greater than string2.
-
-