Class CustomImportOrderCheck
- 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.CustomImportOrderCheck
-
- All Implemented Interfaces:
Configurable
,Contextualizable
public class CustomImportOrderCheck extends AbstractCheck
Checks that the groups of import declarations appear in the order specified by the user. If there is an import but its group is not specified in the configuration such an import should be placed at the end of the import list.
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 contains some imports that have particular meaning for the user.
Use the separator '###' between rules.
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 format of order declaration customizing by user. Type isjava.lang.String
. 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".*"
. -
Property
specialImportsRegExp
- Specify RegExp for SPECIAL_IMPORTS group imports. Type isjava.util.regex.Pattern
. 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
.
To configure the check so that it matches default Eclipse formatter configuration (tested on Kepler and Luna releases):
- group of static imports is on the top
- groups of non-static imports: "java" and "javax" packages first, then "org" and then all other imports
- imports will be sorted in the groups
- groups are separated by single blank line
Notes:
- "com" package is not mentioned on configuration, because it is ignored by Eclipse Kepler and Luna (looks like Eclipse defect)
- configuration below doesn't work in all 100% cases due to inconsistent behavior prior to Mars release, but covers most scenarios
<module name="CustomImportOrder"> <property name="customImportOrderRules" value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS"/> <property name="specialImportsRegExp" value="^org\."/> <property name="sortImportsInGroupAlphabetically" value="true"/> <property name="separateLineBetweenGroups" value="true"/> </module>
To configure the check so that it matches default Eclipse formatter configuration (tested on Mars release):
- group of static imports is on the top
- groups of non-static imports: "java" and "javax" packages first, then "org" and "com", then all other imports as one group
- imports will be sorted in the groups
- groups are separated by one blank line
<module name="CustomImportOrder"> <property name="customImportOrderRules" value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE"/> <property name="specialImportsRegExp" value="^org\."/> <property name="thirdPartyPackageRegExp" value="^com\."/> <property name="sortImportsInGroupAlphabetically" value="true"/> <property name="separateLineBetweenGroups" 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 one blank line
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="CustomImportOrder"> <property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/> <property name="specialImportsRegExp" value="^javax\."/> <property name="standardPackageRegExp" value="^java\."/> <property name="sortImportsInGroupAlphabetically" value="true"/> <property name="separateLineBetweenGroups" value="false"/> </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="CustomImportOrder"/>
To set RegExps for THIRD_PARTY_PACKAGE and STANDARD_JAVA_PACKAGE groups use thirdPartyPackageRegExp and standardPackageRegExp options.
<module name="CustomImportOrder"> <property name="customImportOrderRules" value="STATIC###SAME_PACKAGE(3)###THIRD_PARTY_PACKAGE###STANDARD_JAVA_PACKAGE"/> <property name="thirdPartyPackageRegExp" value="^(com|org)\."/> <property name="standardPackageRegExp" value="^(java|javax)\."/> </module>
Also, this check can be configured to force empty line separator between import groups. For example.
<module name="CustomImportOrder"> <property name="separateLineBetweenGroups" value="true"/> </module>
It is possible to enforce ASCII sort order of imports in groups using the following configuration:
<module name="CustomImportOrder"> <property name="sortImportsInGroupAlphabetically" value="true"/> </module>
Example of ASCII order:
import java.awt.Dialog; import java.awt.Window; import java.awt.color.ColorSpace; import java.awt.Frame; // violation here - in ASCII order 'F' should go before 'c', // as all uppercase come before lowercase letters
To force checking imports sequence such as:
package com.puppycrawl.tools.checkstyle.imports; import com.google.common.annotations.GwtCompatible; import com.google.common.annotations.Beta; import com.google.common.annotations.VisibleForTesting; import org.abego.treelayout.Configuration; import static sun.tools.util.ModifierFilter.ALL_ACCESS; import com.google.common.annotations.GwtCompatible; // violation here - should be in the // THIRD_PARTY_PACKAGE group import android.*;
configure as follows:
<module name="CustomImportOrder"> <property name="customImportOrderRules" value="SAME_PACKAGE(3)###THIRD_PARTY_PACKAGE###STATIC###SPECIAL_IMPORTS"/> <property name="specialImportsRegExp" value="^android\."/> </module>
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 classes/interfaces inherited from class com.puppycrawl.tools.checkstyle.api.AutomaticBean
AutomaticBean.OutputStreamOptions
-
-
Field Summary
Fields Modifier and Type Field Description static java.lang.String
MSG_LEX
A key is pointing to the warning message text in "messages.properties" file.static java.lang.String
MSG_LINE_SEPARATOR
A key is pointing to the warning message text in "messages.properties" file.static java.lang.String
MSG_NONGROUP_EXPECTED
A key is pointing to the warning message text in "messages.properties" file.static java.lang.String
MSG_NONGROUP_IMPORT
A key is pointing to the warning message text in "messages.properties" file.static java.lang.String
MSG_ORDER
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
SAME_PACKAGE_RULE_GROUP
SAME_PACKAGE group name.static java.lang.String
SPECIAL_IMPORTS_RULE_GROUP
SPECIAL_IMPORTS group name.static java.lang.String
STANDARD_JAVA_PACKAGE_RULE_GROUP
STANDARD_JAVA_PACKAGE group name.static java.lang.String
STATIC_RULE_GROUP
STATIC group name.static java.lang.String
THIRD_PARTY_PACKAGE_RULE_GROUP
THIRD_PARTY_PACKAGE group name.
-
Constructor Summary
Constructors Constructor Description CustomImportOrderCheck()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
beginTree(DetailAST rootAST)
Called before the starting to process a tree.void
finishTree(DetailAST rootAST)
Called after finished processing a tree.int[]
getAcceptableTokens()
The configurable token set.int[]
getDefaultTokens()
Returns the default token a check is interested in.int[]
getRequiredTokens()
The tokens that this check must be registered for.void
setCustomImportOrderRules(java.lang.String inputCustomImportOrder)
Setter to specify format of order declaration customizing by user.void
setSeparateLineBetweenGroups(boolean value)
Setter to force empty line separator between import groups.void
setSortImportsInGroupAlphabetically(boolean value)
Setter to force grouping alphabetically, in ASCII sort order.void
setSpecialImportsRegExp(java.util.regex.Pattern regexp)
Setter to specify RegExp for SPECIAL_IMPORTS group imports.void
setStandardPackageRegExp(java.util.regex.Pattern regexp)
Setter to specify RegExp for STANDARD_JAVA_PACKAGE group imports.void
setThirdPartyPackageRegExp(java.util.regex.Pattern regexp)
Setter to specify RegExp for THIRD_PARTY_PACKAGE group imports.void
visitToken(DetailAST ast)
Called to process a token.-
Methods inherited from class com.puppycrawl.tools.checkstyle.api.AbstractCheck
clearMessages, destroy, getFileContents, getLine, getLines, getMessages, getTabWidth, getTokenNames, 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.api.AutomaticBean
configure, contextualize, getConfiguration, setupChild
-
-
-
-
Field Detail
-
MSG_LINE_SEPARATOR
public static final java.lang.String MSG_LINE_SEPARATOR
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
-
MSG_LEX
public static final java.lang.String MSG_LEX
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_NONGROUP_IMPORT
public static final java.lang.String MSG_NONGROUP_IMPORT
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_NONGROUP_EXPECTED
public static final java.lang.String MSG_NONGROUP_EXPECTED
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
MSG_ORDER
public static final java.lang.String MSG_ORDER
A key is pointing to the warning message text in "messages.properties" file.- See Also:
- Constant Field Values
-
STATIC_RULE_GROUP
public static final java.lang.String STATIC_RULE_GROUP
STATIC group name.- See Also:
- Constant Field Values
-
SAME_PACKAGE_RULE_GROUP
public static final java.lang.String SAME_PACKAGE_RULE_GROUP
SAME_PACKAGE group name.- See Also:
- Constant Field Values
-
THIRD_PARTY_PACKAGE_RULE_GROUP
public static final java.lang.String THIRD_PARTY_PACKAGE_RULE_GROUP
THIRD_PARTY_PACKAGE group name.- See Also:
- Constant Field Values
-
STANDARD_JAVA_PACKAGE_RULE_GROUP
public static final java.lang.String STANDARD_JAVA_PACKAGE_RULE_GROUP
STANDARD_JAVA_PACKAGE group name.- See Also:
- Constant Field Values
-
SPECIAL_IMPORTS_RULE_GROUP
public static final java.lang.String SPECIAL_IMPORTS_RULE_GROUP
SPECIAL_IMPORTS group name.- See Also:
- Constant Field Values
-
-
Method Detail
-
setStandardPackageRegExp
public final void setStandardPackageRegExp(java.util.regex.Pattern regexp)
Setter to specify RegExp for STANDARD_JAVA_PACKAGE group imports.- Parameters:
regexp
- user value.
-
setThirdPartyPackageRegExp
public final void setThirdPartyPackageRegExp(java.util.regex.Pattern regexp)
Setter to specify RegExp for THIRD_PARTY_PACKAGE group imports.- Parameters:
regexp
- user value.
-
setSpecialImportsRegExp
public final void setSpecialImportsRegExp(java.util.regex.Pattern regexp)
Setter to specify RegExp for SPECIAL_IMPORTS group imports.- Parameters:
regexp
- user value.
-
setSeparateLineBetweenGroups
public final void setSeparateLineBetweenGroups(boolean value)
Setter to force empty line separator between import groups.- Parameters:
value
- user value.
-
setSortImportsInGroupAlphabetically
public final void setSortImportsInGroupAlphabetically(boolean value)
Setter to force grouping alphabetically, in ASCII sort order.- Parameters:
value
- user value.
-
setCustomImportOrderRules
public final void setCustomImportOrderRules(java.lang.String inputCustomImportOrder)
Setter to specify format of order declaration customizing by user.- Parameters:
inputCustomImportOrder
- user value.
-
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
-
finishTree
public void finishTree(DetailAST rootAST)
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
-
-