Class ImportOrderCheck

All Implemented Interfaces:
Configurable, Contextualizable

public class ImportOrderCheck extends AbstractCheck
Checks the ordering/grouping of imports. Features are:
  • groups type/static 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 type import groups : ensures that a blank line sit between each group
  • type/static import groups aren't separated internally: ensures that each group aren't separated internally by blank line or comment
  • sorts type/static imports inside each group: ensures that imports within each group are in lexicographic order
  • sorts according to case: ensures that the comparison between imports is case-sensitive, in ASCII sort order
  • arrange static imports: ensures the relative order between type imports and static imports (see ImportOrderOption)
  • Property caseSensitive - Control whether string comparison should be case-sensitive or not. Case-sensitive sorting is in ASCII sort order. It affects both type imports and static imports. Type is boolean. Default value is true.
  • Property groups - Specify list of type import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/). If an import matches two or more groups, the best match is selected (closest to the start, and the longest match). All type imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of type groups (the default value) means one group for all type imports. Type is java.lang.String[]. Default value is "".
  • Property option - Specify policy on the relative order between type imports and static imports. Type is com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderOption. Default value is under.
  • Property ordered - Control whether type imports within each group should be sorted. It doesn't affect sorting for static imports. Type is boolean. Default value is true.
  • Property separated - Control whether type import groups should be separated by, at least, one blank line or comment and aren't separated internally. It doesn't affect separations for static imports. Type is boolean. Default value is false.
  • Property separatedStaticGroups - Control whether static import groups should be separated by, at least, one blank line or comment and aren't separated internally. This property has effect only when the property option is set to top or bottom and when property staticGroups is enabled. Type is boolean. Default value is false.
  • Property sortStaticImportsAlphabetically - Control whether static imports located at top or bottom are sorted within the group. Type is boolean. Default value is false.
  • Property staticGroups - Specify list of static import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/). If an import matches two or more groups, the best match is selected (closest to the start, and the longest match). All static imports, which does not match any group, fall into an additional group, located at the end. Thus, the empty list of static groups (the default value) means one group for all static imports. This property has effect only when the property option is set to top or bottom. Type is java.lang.String[]. Default value is "".
  • Property useContainerOrderingForStatic - Control whether to use container ordering (Eclipse IDE term) for static imports or not. Type is boolean. Default value is false.

Parent is com.puppycrawl.tools.checkstyle.TreeWalker

Violation Message Keys:

  • import.groups.separated.internally
  • import.ordering
  • import.separation
Since:
3.2
  • Field Details

    • MSG_SEPARATION

      public static final String MSG_SEPARATION
      A key is pointing to the warning message text in "messages.properties" file.
      See Also:
    • MSG_ORDERING

      public static final String MSG_ORDERING
      A key is pointing to the warning message text in "messages.properties" file.
      See Also:
    • MSG_SEPARATED_IN_GROUP

      public static final String MSG_SEPARATED_IN_GROUP
      A key is pointing to the warning message text in "messages.properties" file.
      See Also:
    • WILDCARD_GROUP_NAME

      private static final String WILDCARD_GROUP_NAME
      The special wildcard that catches all remaining groups.
      See Also:
    • FORWARD_SLASH

      private static final String FORWARD_SLASH
      The Forward slash.
      See Also:
    • EMPTY_PATTERN_ARRAY

      private static final Pattern[] EMPTY_PATTERN_ARRAY
      Empty array of pattern type needed to initialize check.
    • groups

      private String[] groups
      Specify list of type import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/). If an import matches two or more groups, the best match is selected (closest to the start, and the longest match). All type imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of type groups (the default value) means one group for all type imports.
    • staticGroups

      private String[] staticGroups
      Specify list of static import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/). If an import matches two or more groups, the best match is selected (closest to the start, and the longest match). All static imports, which does not match any group, fall into an additional group, located at the end. Thus, the empty list of static groups (the default value) means one group for all static imports. This property has effect only when the property option is set to top or bottom.
    • separated

      private boolean separated
      Control whether type import groups should be separated by, at least, one blank line or comment and aren't separated internally. It doesn't affect separations for static imports.
    • separatedStaticGroups

      private boolean separatedStaticGroups
      Control whether static import groups should be separated by, at least, one blank line or comment and aren't separated internally. This property has effect only when the property option is set to top or bottom and when property staticGroups is enabled.
    • ordered

      private boolean ordered
      Control whether type imports within each group should be sorted. It doesn't affect sorting for static imports.
    • caseSensitive

      private boolean caseSensitive
      Control whether string comparison should be case-sensitive or not. Case-sensitive sorting is in ASCII sort order. It affects both type imports and static imports.
    • lastGroup

      private int lastGroup
      Last imported group.
    • lastImportLine

      private int lastImportLine
      Line number of last import.
    • lastImport

      private String lastImport
      Name of last import.
    • lastImportStatic

      private boolean lastImportStatic
      If last import was static.
    • beforeFirstImport

      private boolean beforeFirstImport
      Whether there were any imports.
    • staticImportsApart

      private boolean staticImportsApart
      Whether static and type import groups should be split apart. When the option property is set to INFLOW, ABOVE or UNDER, both the type and static imports use the properties groups and separated. When the option property is set to TOP or BOTTOM, static imports uses the properties staticGroups and separatedStaticGroups.
    • sortStaticImportsAlphabetically

      Control whether static imports located at top or bottom are sorted within the group.
    • useContainerOrderingForStatic

      Control whether to use container ordering (Eclipse IDE term) for static imports or not.
    • option

      Specify policy on the relative order between type imports and static imports.
    • groupsReg

      private Pattern[] groupsReg
      Complied array of patterns for property groups.
    • staticGroupsReg

      Complied array of patterns for property staticGroups.
  • Constructor Details

  • Method Details

    • setOption

      public void setOption(String optionStr)
      Setter to specify policy on the relative order between type imports and static imports.
      Parameters:
      optionStr - string to decode option from
      Throws:
      IllegalArgumentException - if unable to decode
      Since:
      5.0
    • setGroups

      public void setGroups(String... packageGroups)
      Setter to specify list of type import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/). If an import matches two or more groups, the best match is selected (closest to the start, and the longest match). All type imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of type groups (the default value) means one group for all type imports.
      Parameters:
      packageGroups - a comma-separated list of package names/prefixes.
      Since:
      3.2
    • setStaticGroups

      public void setStaticGroups(String... packageGroups)
      Setter to specify list of static import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. /regexp/). If an import matches two or more groups, the best match is selected (closest to the start, and the longest match). All static imports, which does not match any group, fall into an additional group, located at the end. Thus, the empty list of static groups (the default value) means one group for all static imports. This property has effect only when the property option is set to top or bottom.
      Parameters:
      packageGroups - a comma-separated list of package names/prefixes.
      Since:
      8.12
    • setOrdered

      public void setOrdered(boolean ordered)
      Setter to control whether type imports within each group should be sorted. It doesn't affect sorting for static imports.
      Parameters:
      ordered - whether lexicographic ordering of imports within a group required or not.
      Since:
      3.2
    • setSeparated

      public void setSeparated(boolean separated)
      Setter to control whether type import groups should be separated by, at least, one blank line or comment and aren't separated internally. It doesn't affect separations for static imports.
      Parameters:
      separated - whether groups should be separated by one blank line or comment.
      Since:
      3.2
    • setSeparatedStaticGroups

      public void setSeparatedStaticGroups(boolean separatedStaticGroups)
      Setter to control whether static import groups should be separated by, at least, one blank line or comment and aren't separated internally. This property has effect only when the property option is set to top or bottom and when property staticGroups is enabled.
      Parameters:
      separatedStaticGroups - whether groups should be separated by one blank line or comment.
      Since:
      8.12
    • setCaseSensitive

      public void setCaseSensitive(boolean caseSensitive)
      Setter to control whether string comparison should be case-sensitive or not. Case-sensitive sorting is in ASCII sort order. It affects both type imports and static imports.
      Parameters:
      caseSensitive - whether string comparison should be case-sensitive.
      Since:
      3.3
    • setSortStaticImportsAlphabetically

      public void setSortStaticImportsAlphabetically(boolean sortAlphabetically)
      Setter to control whether static imports located at top or bottom are sorted within the group.
      Parameters:
      sortAlphabetically - true or false.
      Since:
      6.5
    • setUseContainerOrderingForStatic

      public void setUseContainerOrderingForStatic(boolean useContainerOrdering)
      Setter to control 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.
      Since:
      7.1
    • 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 class AbstractCheck
      Returns:
      the default tokens
      See Also:
    • 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 class AbstractCheck
      Returns:
      the token set this check is designed for.
      See Also:
    • getRequiredTokens

      public int[] getRequiredTokens()
      Description copied from class: AbstractCheck
      The tokens that this check must be registered for.
      Specified by:
      getRequiredTokens in class AbstractCheck
      Returns:
      the token set this must be registered for.
      See Also:
    • 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 class AbstractCheck
      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 class AbstractCheck
      Parameters:
      ast - the token to process
    • doVisitToken

      private void doVisitToken(FullIdent ident, boolean isStatic, boolean previous, DetailAST ast)
      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).
      ast - node of the AST.
    • needSeparator

      private boolean needSeparator(boolean isStatic)
      Checks whether import groups should be separated.
      Parameters:
      isStatic - whether the token is static or not.
      Returns:
      true if imports groups should be separated.
    • isSeparatorInGroup

      private boolean isSeparatorInGroup(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.
    • isSeparatorBeforeImport

      private boolean isSeparatorBeforeImport(int line)
      Checks whether there is any separator before current import.
      Parameters:
      line - the line of the current import.
      Returns:
      true if there is separator before current import which isn't the first import.
    • doVisitTokenInSameGroup

      private void doVisitTokenInSameGroup(boolean isStatic, boolean previous, String name, DetailAST ast)
      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.
      ast - node of the AST.
    • isWrongOrder

      private boolean isWrongOrder(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(String importName1, 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 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)
    • getImportContainer

      private static String getImportContainer(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(boolean isStatic, String name)
      Finds out what group the specified import belongs to.
      Parameters:
      isStatic - whether the token is static or not.
      name - the import name to find.
      Returns:
      group number for given import name.
    • getGroupNumber

      private static int getGroupNumber(Pattern[] patterns, String name)
      Finds out what group the specified import belongs to.
      Parameters:
      patterns - groups to check.
      name - the import name to find.
      Returns:
      group number for given import name.
    • compare

      private static int compare(String string1, 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 than 0 if string1 is lexicographically less than the string2; and a value greater than 0 if string1 is lexicographically greater than string2
    • compilePatterns

      private static Pattern[] compilePatterns(String... packageGroups)
      Compiles the list of package groups and the order they should occur in the file.
      Parameters:
      packageGroups - a comma-separated list of package names/prefixes.
      Returns:
      array of compiled patterns.
      Throws:
      IllegalArgumentException - if any of the package groups are not valid.