Class CustomImportOrderCheck
- All Implemented Interfaces:
Configurable
,Contextualizable
The rule consists of:
- STATIC group. This group sets the ordering of static imports.
-
SAME_PACKAGE(n) group. This group sets the ordering of the same package imports.
Imports are considered on SAME_PACKAGE group if n first domains in package
name and import name are identical:
package java.util.concurrent.locks; import java.io.File; import java.util.*; //#1 import java.util.List; //#2 import java.util.StringTokenizer; //#3 import java.util.concurrent.*; //#4 import java.util.concurrent.AbstractExecutorService; //#5 import java.util.concurrent.locks.LockSupport; //#6 import java.util.regex.Pattern; //#7 import java.util.regex.Matcher; //#8
If we have SAME_PACKAGE(3) on configuration file, imports #4-6 will be considered as a SAME_PACKAGE group (java.util.concurrent.*, java.util.concurrent.AbstractExecutorService, java.util.concurrent.locks.LockSupport). SAME_PACKAGE(2) will include #1-8. SAME_PACKAGE(4) will include only #6. SAME_PACKAGE(5) will result in no imports assigned to SAME_PACKAGE group because actual package java.util.concurrent.locks has only 4 domains. - THIRD_PARTY_PACKAGE group. This group sets ordering of third party imports. Third party imports are all imports except STATIC, SAME_PACKAGE(n), STANDARD_JAVA_PACKAGE and SPECIAL_IMPORTS.
- STANDARD_JAVA_PACKAGE group. By default, this group sets ordering of standard java/javax imports.
- SPECIAL_IMPORTS group. This group may contain some imports that have particular meaning for the user.
Rules are configured as a comma-separated ordered list.
Note: '###' group separator is deprecated (in favor of a comma-separated list), but is currently supported for backward compatibility.
To set RegExps for THIRD_PARTY_PACKAGE and STANDARD_JAVA_PACKAGE groups use thirdPartyPackageRegExp and standardPackageRegExp options.
Pretty often one import can match more than one group. For example, static import from standard package or regular expressions are configured to allow one import match multiple groups. In this case, group will be assigned according to priorities:
- STATIC has top priority
- SAME_PACKAGE has second priority
- STANDARD_JAVA_PACKAGE and SPECIAL_IMPORTS will compete using "best match" rule: longer matching substring wins; in case of the same length, lower position of matching substring wins; if position is the same, order of rules in configuration solves the puzzle.
- THIRD_PARTY has the least priority
Few examples to illustrate "best match":
1. patterns STANDARD_JAVA_PACKAGE = "Check", SPECIAL_IMPORTS="ImportOrderCheck" and input file:
import com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck; import com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck;
Result: imports will be assigned to SPECIAL_IMPORTS, because matching substring length is 16. Matching substring for STANDARD_JAVA_PACKAGE is 5.
2. patterns STANDARD_JAVA_PACKAGE = "Check", SPECIAL_IMPORTS="Avoid" and file:
import com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck;
Result: import will be assigned to SPECIAL_IMPORTS. Matching substring length is 5 for both patterns. However, "Avoid" position is lower than "Check" position.
-
Property
customImportOrderRules
- Specify ordered list of import groups. Type isjava.lang.String[]
. Default value is""
. -
Property
separateLineBetweenGroups
- Force empty line separator between import groups. Type isboolean
. Default value istrue
. -
Property
sortImportsInGroupAlphabetically
- Force grouping alphabetically, in ASCII sort order. Type isboolean
. Default value isfalse
. -
Property
specialImportsRegExp
- Specify RegExp for SPECIAL_IMPORTS group imports. Type isjava.util.regex.Pattern
. Default value is"^$"
. -
Property
standardPackageRegExp
- Specify RegExp for STANDARD_JAVA_PACKAGE group imports. Type isjava.util.regex.Pattern
. Default value is"^(java|javax)\."
. -
Property
thirdPartyPackageRegExp
- Specify RegExp for THIRD_PARTY_PACKAGE group imports. Type isjava.util.regex.Pattern
. Default value is".*"
.
Parent is com.puppycrawl.tools.checkstyle.TreeWalker
Violation Message Keys:
-
custom.import.order
-
custom.import.order.lex
-
custom.import.order.line.separator
-
custom.import.order.nonGroup.expected
-
custom.import.order.nonGroup.import
-
custom.import.order.separated.internally
- Since:
- 5.8
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final class
Contains import attributes as line number, import full path, import group.private static final class
Contains matching attributes assisting in definition of "best matching" group for import.Nested classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
AbstractAutomaticBean.OutputStreamOptions
-
Field Summary
FieldsModifier and TypeFieldDescriptionSpecify ordered list of import groups.private static final Pattern
Pattern used to separate groups of imports.private final List<CustomImportOrderCheck.ImportDetails>
Contains objects with import attributes.static final String
A key is pointing to the warning message text in "messages.properties" file.static final String
A key is pointing to the warning message text in "messages.properties" file.static final String
A key is pointing to the warning message text in "messages.properties" file.static final String
A key is pointing to the warning message text in "messages.properties" file.static final String
A key is pointing to the warning message text in "messages.properties" file.static final String
A key is pointing to the warning message text in "messages.properties" file.private static final String
NON_GROUP group name.static final String
SAME_PACKAGE group name.private String
Specify RegExp for SAME_PACKAGE group imports.private int
Number of first domains for SAME_PACKAGE group.private boolean
Force empty line separator between import groups.private boolean
Force grouping alphabetically, in ASCII sort order.static final String
SPECIAL_IMPORTS group name.private Pattern
Specify RegExp for SPECIAL_IMPORTS group imports.static final String
STANDARD_JAVA_PACKAGE group name.private Pattern
Specify RegExp for STANDARD_JAVA_PACKAGE group imports.static final String
STATIC group name.static final String
THIRD_PARTY_PACKAGE group name.private Pattern
Specify RegExp for THIRD_PARTY_PACKAGE group imports. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate void
addRulesToList
(String ruleStr) Parses ordering rule and adds it to the list with rules.void
Called before the starting to process a tree.private static int
compareImports
(String import1, String import2) Checks compare two import paths.private static String
createSamePackageRegexp
(int firstPackageDomainsCount, DetailAST packageNode) Creates samePackageDomainsRegExp of the first package domains.private static CustomImportOrderCheck.RuleMatchForImport
findBetterPatternMatch
(String importPath, String group, Pattern regExp, CustomImportOrderCheck.RuleMatchForImport currentBestMatch) Tries to find better matching regular expression: longer matching substring wins; in case of the same length, lower position of matching substring wins.private void
Examine the order of all the imports and log any violations.void
finishTree
(DetailAST rootAST) Called after finished processing a tree.int[]
The configurable token set.private int
getCountOfEmptyLinesBetween
(int fromLineNo, int toLineNo) Counts empty lines between given parameters.int[]
Returns the default token a check is interested in.private static String
getFirstDomainsFromIdent
(int firstPackageDomainsCount, String packageFullPath) Extracts defined amount of domains from the left side of package/import identifier.private String
Get first import group.private static String
getFullImportIdent
(DetailAST token) Forms import full path.private String
getImportGroup
(boolean isStatic, String importPath) Get import valid group.private String
getNextImportGroup
(int currentGroupNumber) Get next import group.int[]
The tokens that this check must be registered for.private boolean
hasAnyImportInCurrentGroup
(String currentGroup) Checks if current group contains any import.private boolean
isAlphabeticalOrderBroken
(String previousImport, String currentImport) Examine alphabetical order of imports.private boolean
isEmptyLineMissed
(CustomImportOrderCheck.ImportDetails previousImportObject, CustomImportOrderCheck.ImportDetails currentImportObject) Examine empty lines between groups.private boolean
isSeparatedByExtraEmptyLine
(CustomImportOrderCheck.ImportDetails previousImportObject, CustomImportOrderCheck.ImportDetails currentImportObject) Examine that imports separated by more than one empty line.private void
logWrongImportGroupOrder
(DetailAST importAST, String importGroup, String currentGroupNumber, String fullImportIdent) Log wrong import group order.final void
setCustomImportOrderRules
(String... rules) Setter to specify ordered list of import groups.final void
setSeparateLineBetweenGroups
(boolean value) Setter to force empty line separator between import groups.final void
setSortImportsInGroupAlphabetically
(boolean value) Setter to force grouping alphabetically, in ASCII sort order.final void
setSpecialImportsRegExp
(Pattern regexp) Setter to specify RegExp for SPECIAL_IMPORTS group imports.final void
setStandardPackageRegExp
(Pattern regexp) Setter to specify RegExp for STANDARD_JAVA_PACKAGE group imports.final void
setThirdPartyPackageRegExp
(Pattern regexp) Setter to specify RegExp for THIRD_PARTY_PACKAGE group imports.private void
validateExtraEmptyLine
(CustomImportOrderCheck.ImportDetails previousImport, CustomImportOrderCheck.ImportDetails importObject, String fullImportIdent) Log violation if extra empty line is present.private void
validateMissedEmptyLine
(CustomImportOrderCheck.ImportDetails previousImport, CustomImportOrderCheck.ImportDetails importObject, String fullImportIdent) Log violation if empty line is missed.void
visitToken
(DetailAST ast) Called to process a token.Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck
clearViolations, destroy, getFileContents, getFilePath, getLine, getLineCodePoints, getLines, getTabWidth, getTokenNames, getViolations, init, isCommentNodesRequired, leaveToken, log, log, log, setFileContents, setTabWidth, setTokens
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractViolationReporter
finishLocalSetup, getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, setId, setSeverity
Methods inherited from class com.puppycrawl.tools.checkstyle.AbstractAutomaticBean
configure, contextualize, getConfiguration, setupChild
-
Field Details
-
MSG_LINE_SEPARATOR
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
MSG_SEPARATED_IN_GROUP
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
MSG_LEX
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
MSG_NONGROUP_IMPORT
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
MSG_NONGROUP_EXPECTED
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
MSG_ORDER
A key is pointing to the warning message text in "messages.properties" file.- See Also:
-
STATIC_RULE_GROUP
STATIC group name.- See Also:
-
SAME_PACKAGE_RULE_GROUP
SAME_PACKAGE group name.- See Also:
-
THIRD_PARTY_PACKAGE_RULE_GROUP
THIRD_PARTY_PACKAGE group name.- See Also:
-
STANDARD_JAVA_PACKAGE_RULE_GROUP
STANDARD_JAVA_PACKAGE group name.- See Also:
-
SPECIAL_IMPORTS_RULE_GROUP
SPECIAL_IMPORTS group name.- See Also:
-
NON_GROUP_RULE_GROUP
NON_GROUP group name.- See Also:
-
GROUP_SEPARATOR_PATTERN
Pattern used to separate groups of imports. -
customImportOrderRules
Specify ordered list of import groups. -
importToGroupList
Contains objects with import attributes. -
samePackageDomainsRegExp
Specify RegExp for SAME_PACKAGE group imports. -
standardPackageRegExp
Specify RegExp for STANDARD_JAVA_PACKAGE group imports. -
thirdPartyPackageRegExp
Specify RegExp for THIRD_PARTY_PACKAGE group imports. -
specialImportsRegExp
Specify RegExp for SPECIAL_IMPORTS group imports. -
separateLineBetweenGroups
Force empty line separator between import groups. -
sortImportsInGroupAlphabetically
Force grouping alphabetically, in ASCII sort order. -
samePackageMatchingDepth
Number of first domains for SAME_PACKAGE group.
-
-
Constructor Details
-
CustomImportOrderCheck
public CustomImportOrderCheck()
-
-
Method Details
-
setStandardPackageRegExp
Setter to specify RegExp for STANDARD_JAVA_PACKAGE group imports.- Parameters:
regexp
- user value.- Since:
- 5.8
-
setThirdPartyPackageRegExp
Setter to specify RegExp for THIRD_PARTY_PACKAGE group imports.- Parameters:
regexp
- user value.- Since:
- 5.8
-
setSpecialImportsRegExp
Setter to specify RegExp for SPECIAL_IMPORTS group imports.- Parameters:
regexp
- user value.- Since:
- 5.8
-
setSeparateLineBetweenGroups
Setter to force empty line separator between import groups.- Parameters:
value
- user value.- Since:
- 5.8
-
setSortImportsInGroupAlphabetically
Setter to force grouping alphabetically, in ASCII sort order.- Parameters:
value
- user value.- Since:
- 5.8
-
setCustomImportOrderRules
Setter to specify ordered list of import groups.- Parameters:
rules
- user value.- Since:
- 5.8
-
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:
-
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:
-
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:
-
beginTree
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
Description copied from class:AbstractCheck
Called to process a token.- Overrides:
visitToken
in classAbstractCheck
- Parameters:
ast
- the token to process
-
finishTree
Description copied from class:AbstractCheck
Called after finished processing a tree. Ideal place to report on information collected whilst processing a tree.- Overrides:
finishTree
in classAbstractCheck
- Parameters:
rootAST
- the root of the tree
-
finishImportList
Examine the order of all the imports and log any violations. -
validateMissedEmptyLine
private void validateMissedEmptyLine(CustomImportOrderCheck.ImportDetails previousImport, CustomImportOrderCheck.ImportDetails importObject, String fullImportIdent) Log violation if empty line is missed.- Parameters:
previousImport
- previous import from current group.importObject
- current import.fullImportIdent
- full import identifier.
-
validateExtraEmptyLine
private void validateExtraEmptyLine(CustomImportOrderCheck.ImportDetails previousImport, CustomImportOrderCheck.ImportDetails importObject, String fullImportIdent) Log violation if extra empty line is present.- Parameters:
previousImport
- previous import from current group.importObject
- current import.fullImportIdent
- full import identifier.
-
getFirstGroup
Get first import group.- Returns:
- first import group of file.
-
isAlphabeticalOrderBroken
Examine alphabetical order of imports.- Parameters:
previousImport
- previous import of current group.currentImport
- current import.- Returns:
- true, if previous and current import are not in alphabetical order.
-
isEmptyLineMissed
private boolean isEmptyLineMissed(CustomImportOrderCheck.ImportDetails previousImportObject, CustomImportOrderCheck.ImportDetails currentImportObject) Examine empty lines between groups.- Parameters:
previousImportObject
- previous import in current group.currentImportObject
- current import.- Returns:
- true, if current import NOT separated from previous import by empty line.
-
isSeparatedByExtraEmptyLine
private boolean isSeparatedByExtraEmptyLine(CustomImportOrderCheck.ImportDetails previousImportObject, CustomImportOrderCheck.ImportDetails currentImportObject) Examine that imports separated by more than one empty line.- Parameters:
previousImportObject
- previous import in current group.currentImportObject
- current import.- Returns:
- true, if current import separated from previous by more than one empty line.
-
logWrongImportGroupOrder
private void logWrongImportGroupOrder(DetailAST importAST, String importGroup, String currentGroupNumber, String fullImportIdent) Log wrong import group order.- Parameters:
importAST
- import ast.importGroup
- import group.currentGroupNumber
- current group number we are checking.fullImportIdent
- full import name.
-
getNextImportGroup
Get next import group.- Parameters:
currentGroupNumber
- current group number.- Returns:
- next import group.
-
hasAnyImportInCurrentGroup
Checks if current group contains any import.- Parameters:
currentGroup
- current group.- Returns:
- true, if current group contains at least one import.
-
getImportGroup
Get import valid group.- Parameters:
isStatic
- is static import.importPath
- full import path.- Returns:
- import valid group.
-
findBetterPatternMatch
private static CustomImportOrderCheck.RuleMatchForImport findBetterPatternMatch(String importPath, String group, Pattern regExp, CustomImportOrderCheck.RuleMatchForImport currentBestMatch) Tries to find better matching regular expression: longer matching substring wins; in case of the same length, lower position of matching substring wins.- Parameters:
importPath
- Full import identifiergroup
- Import group we are trying to assign the importregExp
- Regular expression for import groupcurrentBestMatch
- object with currently best match- Returns:
- better match (if found) or the same (currentBestMatch)
-
compareImports
Checks compare two import paths.- Parameters:
import1
- current import.import2
- previous import.- Returns:
- a negative integer, zero, or a positive integer as the specified String is greater than, equal to, or less than this String, ignoring case considerations.
-
getCountOfEmptyLinesBetween
Counts empty lines between given parameters.- Parameters:
fromLineNo
- One-based line number of previous import.toLineNo
- One-based line number of current import.- Returns:
- count of empty lines between given parameters, exclusive, eg., (fromLineNo, toLineNo).
-
getFullImportIdent
Forms import full path.- Parameters:
token
- current token.- Returns:
- full path or null.
-
addRulesToList
Parses ordering rule and adds it to the list with rules.- Parameters:
ruleStr
- String with rule.- Throws:
IllegalArgumentException
- when SAME_PACKAGE rule parameter is not positive integerIllegalStateException
- when ruleStr is unexpected value
-
createSamePackageRegexp
Creates samePackageDomainsRegExp of the first package domains.- Parameters:
firstPackageDomainsCount
- number of first package domains.packageNode
- package node.- Returns:
- same package regexp.
-
getFirstDomainsFromIdent
private static String getFirstDomainsFromIdent(int firstPackageDomainsCount, String packageFullPath) Extracts defined amount of domains from the left side of package/import identifier.- Parameters:
firstPackageDomainsCount
- number of first package domains.packageFullPath
- full identifier containing path to package or imported object.- Returns:
- String with defined amount of domains or full identifier (if full identifier had less domain than specified)
-