001/////////////////////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code and other text files for adherence to a set of rules. 003// Copyright (C) 2001-2025 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018/////////////////////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.checks.metrics; 021 022import java.util.regex.Pattern; 023 024import com.puppycrawl.tools.checkstyle.api.TokenTypes; 025 026/** 027 * <div> 028 * Measures the number of distinct classes that are instantiated 029 * within the given class or record. This type of coupling is not caused by inheritance or 030 * the object-oriented paradigm. Generally speaking, any data type with other 031 * data types as members or local variable that is an instantiation (object) 032 * of another class has data abstraction coupling (DAC). The higher the DAC, 033 * the more complex the structure of the class. 034 * </div> 035 * 036 * <p> 037 * This check processes files in the following way: 038 * </p> 039 * <ol> 040 * <li> 041 * Iterates over the list of tokens (defined below) and counts all mentioned classes. 042 * <ul> 043 * <li> 044 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#IMPORT"> 045 * PACKAGE_DEF</a> 046 * </li> 047 * <li> 048 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#IMPORT"> 049 * IMPORT</a> 050 * </li> 051 * <li> 052 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#CLASS_DEF"> 053 * CLASS_DEF</a> 054 * </li> 055 * <li> 056 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#INTERFACE_DEF"> 057 * INTERFACE_DEF</a> 058 * </li> 059 * <li> 060 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#ENUM_DEF"> 061 * ENUM_DEF</a> 062 * </li> 063 * <li> 064 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_NEW"> 065 * LITERAL_NEW</a> 066 * </li> 067 * <li> 068 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#RECORD_DEF"> 069 * RECORD_DEF</a> 070 * </li> 071 * </ul> 072 * </li> 073 * <li> 074 * If a class was imported with direct import (i.e. {@code import java.math.BigDecimal}), 075 * or the class was referenced with the package name (i.e. {@code java.math.BigDecimal value}) 076 * and the package was added to the {@code excludedPackages} parameter, the class 077 * does not increase complexity. 078 * </li> 079 * <li> 080 * If a class name was added to the {@code excludedClasses} parameter, 081 * the class does not increase complexity. 082 * </li> 083 * </ol> 084 * 085 * @since 3.4 086 */ 087public final class ClassDataAbstractionCouplingCheck 088 extends AbstractClassCouplingCheck { 089 090 /** 091 * A key is pointing to the warning message text in "messages.properties" 092 * file. 093 */ 094 public static final String MSG_KEY = "classDataAbstractionCoupling"; 095 096 /** Default allowed complexity. */ 097 private static final int DEFAULT_MAX = 7; 098 099 /** Creates bew instance of the check. */ 100 public ClassDataAbstractionCouplingCheck() { 101 super(DEFAULT_MAX); 102 } 103 104 @Override 105 public int[] getRequiredTokens() { 106 return new int[] { 107 TokenTypes.PACKAGE_DEF, 108 TokenTypes.IMPORT, 109 TokenTypes.CLASS_DEF, 110 TokenTypes.INTERFACE_DEF, 111 TokenTypes.ENUM_DEF, 112 TokenTypes.LITERAL_NEW, 113 TokenTypes.RECORD_DEF, 114 }; 115 } 116 117 @Override 118 public int[] getAcceptableTokens() { 119 return getRequiredTokens(); 120 } 121 122 @Override 123 protected String getLogMessageId() { 124 return MSG_KEY; 125 } 126 127 /** 128 * Setter to specify user-configured regular expressions to ignore classes. 129 * 130 * @param from array representing regular expressions of classes to ignore. 131 * @propertySince 7.7 132 * @noinspection RedundantMethodOverride 133 * @noinspectionreason Display module's unique property version 134 */ 135 @Override 136 public void setExcludeClassesRegexps(Pattern... from) { 137 super.setExcludeClassesRegexps(from); 138 } 139 140 /** 141 * Setter to specify user-configured class names to ignore. 142 * 143 * @param excludedClasses classes to ignore. 144 * @propertySince 5.7 145 * @noinspection RedundantMethodOverride 146 * @noinspectionreason Display module's unique property version 147 */ 148 @Override 149 public void setExcludedClasses(String... excludedClasses) { 150 super.setExcludedClasses(excludedClasses); 151 } 152 153 /** 154 * Setter to specify user-configured packages to ignore. 155 * 156 * @param excludedPackages packages to ignore. 157 * @throws IllegalArgumentException if there are invalid identifiers among the packages. 158 * @propertySince 7.7 159 * @noinspection RedundantMethodOverride 160 * @noinspectionreason Display module's unique property version 161 */ 162 @Override 163 public void setExcludedPackages(String... excludedPackages) { 164 super.setExcludedPackages(excludedPackages); 165 } 166 167}