1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.site;
21
22 import java.beans.Introspector;
23 import java.util.Collections;
24 import java.util.LinkedHashMap;
25 import java.util.Map;
26 import java.util.regex.Pattern;
27
28 import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
29 import com.puppycrawl.tools.checkstyle.api.DetailAST;
30 import com.puppycrawl.tools.checkstyle.api.DetailNode;
31 import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
32 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
33 import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
34 import com.puppycrawl.tools.checkstyle.utils.BlockCommentPosition;
35
36
37
38
39
40 @FileStatefulCheck
41 public class ClassAndPropertiesSettersJavadocScraper extends AbstractJavadocCheck {
42
43
44
45
46
47 private static final Map<String, DetailNode> JAVADOC_FOR_MODULE_OR_PROPERTY =
48 new LinkedHashMap<>();
49
50
51 private static String moduleName = "";
52
53
54
55
56
57
58 public static void initialize(String newModuleName) {
59 JAVADOC_FOR_MODULE_OR_PROPERTY.clear();
60 moduleName = newModuleName;
61 }
62
63
64
65
66
67
68 public static Map<String, DetailNode> getJavadocsForModuleOrProperty() {
69 return Collections.unmodifiableMap(JAVADOC_FOR_MODULE_OR_PROPERTY);
70 }
71
72 @Override
73 public int[] getDefaultJavadocTokens() {
74 return new int[] {
75 JavadocTokenTypes.JAVADOC,
76 };
77 }
78
79 @Override
80 public void visitJavadocToken(DetailNode ast) {
81 final DetailAST blockCommentAst = getBlockCommentAst();
82 if (BlockCommentPosition.isOnMethod(blockCommentAst)) {
83 final DetailAST methodDef = getParentAst(blockCommentAst, TokenTypes.METHOD_DEF);
84 if (methodDef != null
85 && isSetterMethod(methodDef)
86 && isMethodOfScrapedModule(methodDef)) {
87 final String methodName = methodDef.findFirstToken(TokenTypes.IDENT).getText();
88 final String propertyName = getPropertyName(methodName);
89 JAVADOC_FOR_MODULE_OR_PROPERTY.put(propertyName, ast);
90 }
91
92 }
93 else if (BlockCommentPosition.isOnClass(blockCommentAst)) {
94 final DetailAST classDef = getParentAst(blockCommentAst, TokenTypes.CLASS_DEF);
95 if (classDef != null) {
96 final String className = classDef.findFirstToken(TokenTypes.IDENT).getText();
97 if (className.equals(moduleName)) {
98 JAVADOC_FOR_MODULE_OR_PROPERTY.put(moduleName, ast);
99 }
100 }
101 }
102 }
103
104
105
106
107
108
109
110
111
112
113 private static boolean isMethodOfScrapedModule(DetailAST methodDef) {
114 final DetailAST classDef = getParentAst(methodDef, TokenTypes.CLASS_DEF);
115
116 boolean isMethodOfModule = false;
117 if (classDef != null) {
118 final String className = classDef.findFirstToken(TokenTypes.IDENT).getText();
119 isMethodOfModule = className.equals(moduleName);
120 }
121
122 return isMethodOfModule;
123 }
124
125
126
127
128
129
130
131
132
133 private static DetailAST getParentAst(DetailAST ast, int type) {
134 DetailAST node = ast.getParent();
135
136 while (node != null && node.getType() != type) {
137 node = node.getParent();
138 }
139
140 return node;
141 }
142
143
144
145
146
147
148
149
150
151 private static String getPropertyName(String setterName) {
152 return Introspector.decapitalize(setterName.substring("set".length()));
153 }
154
155
156
157
158
159
160
161 private static boolean isSetterMethod(DetailAST ast) {
162 boolean setterMethod = false;
163
164 if (ast.getType() == TokenTypes.METHOD_DEF) {
165 final DetailAST type = ast.findFirstToken(TokenTypes.TYPE);
166 final String name = type.getNextSibling().getText();
167 final Pattern setterPattern = Pattern.compile("^set[A-Z].*");
168
169 setterMethod = setterPattern.matcher(name).matches();
170 }
171 return setterMethod;
172 }
173 }