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.checks.imports;
21
22 import java.net.URI;
23 import java.util.Collections;
24 import java.util.Set;
25 import java.util.regex.Pattern;
26
27 import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
28 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
29 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
30 import com.puppycrawl.tools.checkstyle.api.DetailAST;
31 import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder;
32 import com.puppycrawl.tools.checkstyle.api.FullIdent;
33 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
34
35
36
37
38
39
40
41
42
43
44
45
46
47 @FileStatefulCheck
48 public class ImportControlCheck extends AbstractCheck implements ExternalResourceHolder {
49
50
51
52
53
54 public static final String MSG_MISSING_FILE = "import.control.missing.file";
55
56
57
58
59
60 public static final String MSG_UNKNOWN_PKG = "import.control.unknown.pkg";
61
62
63
64
65
66 public static final String MSG_DISALLOWED = "import.control.disallowed";
67
68
69
70
71 private static final String UNABLE_TO_LOAD = "Unable to load ";
72
73
74 private URI file;
75
76
77 private Pattern path = Pattern.compile(".*");
78
79 private boolean processCurrentFile;
80
81
82 private PkgImportControl root;
83
84 private String packageName;
85
86 private String fileName;
87
88
89
90
91
92 private AbstractImportControl currentImportControl;
93
94 @Override
95 public int[] getDefaultTokens() {
96 return getRequiredTokens();
97 }
98
99 @Override
100 public int[] getAcceptableTokens() {
101 return getRequiredTokens();
102 }
103
104 @Override
105 public int[] getRequiredTokens() {
106 return new int[] {TokenTypes.PACKAGE_DEF, TokenTypes.IMPORT, TokenTypes.STATIC_IMPORT, };
107 }
108
109 @Override
110 public void beginTree(DetailAST rootAST) {
111 currentImportControl = null;
112 processCurrentFile = path.matcher(getFileContents().getFileName()).find();
113 fileName = getFileContents().getText().getFile().getName();
114
115 final int period = fileName.lastIndexOf('.');
116
117 if (period != -1) {
118 fileName = fileName.substring(0, period);
119 }
120 }
121
122 @Override
123 public void visitToken(DetailAST ast) {
124 if (processCurrentFile) {
125 if (ast.getType() == TokenTypes.PACKAGE_DEF) {
126 if (root == null) {
127 log(ast, MSG_MISSING_FILE);
128 }
129 else {
130 packageName = getPackageText(ast);
131 currentImportControl = root.locateFinest(packageName, fileName);
132 if (currentImportControl == null) {
133 log(ast, MSG_UNKNOWN_PKG);
134 }
135 }
136 }
137 else if (currentImportControl != null) {
138 final String importText = getImportText(ast);
139 final AccessResult access = currentImportControl.checkAccess(packageName, fileName,
140 importText);
141 if (access != AccessResult.ALLOWED) {
142 log(ast, MSG_DISALLOWED, importText);
143 }
144 }
145 }
146 }
147
148 @Override
149 public Set<String> getExternalResourceLocations() {
150 return Collections.singleton(file.toString());
151 }
152
153
154
155
156
157
158 private static String getPackageText(DetailAST ast) {
159 final DetailAST nameAST = ast.getLastChild().getPreviousSibling();
160 return FullIdent.createFullIdent(nameAST).getText();
161 }
162
163
164
165
166
167
168 private static String getImportText(DetailAST ast) {
169 final FullIdent imp;
170 if (ast.getType() == TokenTypes.IMPORT) {
171 imp = FullIdent.createFullIdentBelow(ast);
172 }
173 else {
174
175 imp = FullIdent.createFullIdent(ast
176 .getFirstChild().getNextSibling());
177 }
178 return imp.getText();
179 }
180
181
182
183
184
185
186
187
188 public void setFile(URI uri) {
189
190 if (uri != null) {
191 try {
192 root = ImportControlLoader.load(uri);
193 file = uri;
194 }
195 catch (CheckstyleException ex) {
196 throw new IllegalArgumentException(UNABLE_TO_LOAD + uri, ex);
197 }
198 }
199 }
200
201
202
203
204
205 public void setPath(Pattern pattern) {
206 path = pattern;
207 }
208
209 }