1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.puppycrawl.tools.checkstyle.checks.indentation;
20
21 import com.google.common.collect.Maps;
22 import com.puppycrawl.tools.checkstyle.api.DetailAST;
23 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.Map;
27 import java.util.Set;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31
32
33
34
35
36 public class HandlerFactory
37 {
38
39 private static final Log LOG =
40 LogFactory.getLog("com.puppycrawl.tools.checkstyle.checks.indentation");
41
42
43
44
45 private final Map<Integer, Constructor<?>> typeHandlers =
46 Maps.newHashMap();
47
48
49
50
51
52
53
54
55
56 private void register(int type, Class<?> handlerClass)
57 {
58 try {
59 final Constructor<?> ctor = handlerClass
60 .getConstructor(new Class[] {IndentationCheck.class,
61 DetailAST.class,
62 ExpressionHandler.class,
63 });
64 typeHandlers.put(type, ctor);
65 }
66
67 catch (final NoSuchMethodException e) {
68 throw new RuntimeException("couldn't find ctor for "
69 + handlerClass);
70 }
71 catch (final SecurityException e) {
72 LOG.debug("couldn't find ctor for " + handlerClass, e);
73 throw new RuntimeException("couldn't find ctor for "
74 + handlerClass);
75 }
76
77 }
78
79
80 public HandlerFactory()
81 {
82 register(TokenTypes.CASE_GROUP, CaseHandler.class);
83 register(TokenTypes.LITERAL_SWITCH, SwitchHandler.class);
84 register(TokenTypes.SLIST, SlistHandler.class);
85 register(TokenTypes.PACKAGE_DEF, PackageDefHandler.class);
86 register(TokenTypes.LITERAL_ELSE, ElseHandler.class);
87 register(TokenTypes.LITERAL_IF, IfHandler.class);
88 register(TokenTypes.LITERAL_TRY, TryHandler.class);
89 register(TokenTypes.LITERAL_CATCH, CatchHandler.class);
90 register(TokenTypes.LITERAL_FINALLY, FinallyHandler.class);
91 register(TokenTypes.LITERAL_DO, DoWhileHandler.class);
92 register(TokenTypes.LITERAL_WHILE, WhileHandler.class);
93 register(TokenTypes.LITERAL_FOR, ForHandler.class);
94 register(TokenTypes.METHOD_DEF, MethodDefHandler.class);
95 register(TokenTypes.CTOR_DEF, MethodDefHandler.class);
96 register(TokenTypes.CLASS_DEF, ClassDefHandler.class);
97 register(TokenTypes.ENUM_DEF, ClassDefHandler.class);
98 register(TokenTypes.OBJBLOCK, ObjectBlockHandler.class);
99 register(TokenTypes.INTERFACE_DEF, ClassDefHandler.class);
100 register(TokenTypes.IMPORT, ImportHandler.class);
101 register(TokenTypes.ARRAY_INIT, ArrayInitHandler.class);
102 register(TokenTypes.METHOD_CALL, MethodCallHandler.class);
103 register(TokenTypes.CTOR_CALL, MethodCallHandler.class);
104 register(TokenTypes.LABELED_STAT, LabelHandler.class);
105 register(TokenTypes.STATIC_INIT, StaticInitHandler.class);
106 register(TokenTypes.INSTANCE_INIT, SlistHandler.class);
107 register(TokenTypes.VARIABLE_DEF, MemberDefHandler.class);
108 register(TokenTypes.LITERAL_NEW, NewHandler.class);
109 register(TokenTypes.INDEX_OP, IndexHandler.class);
110 }
111
112
113
114
115
116
117
118 public boolean isHandledType(int type)
119 {
120 final Set<Integer> typeSet = typeHandlers.keySet();
121 return typeSet.contains(type);
122 }
123
124
125
126
127
128
129 public int[] getHandledTypes()
130 {
131 final Set<Integer> typeSet = typeHandlers.keySet();
132 final int[] types = new int[typeSet.size()];
133 int index = 0;
134 for (final Integer val : typeSet) {
135 types[index++] = val;
136 }
137
138 return types;
139 }
140
141
142
143
144
145
146
147
148
149
150 public ExpressionHandler getHandler(IndentationCheck indentCheck,
151 DetailAST ast, ExpressionHandler parent)
152 {
153 final ExpressionHandler handler =
154 createdHandlers.get(ast);
155 if (handler != null) {
156 return handler;
157 }
158
159 if (ast.getType() == TokenTypes.METHOD_CALL) {
160 return createMethodCallHandler(indentCheck, ast, parent);
161 }
162
163 ExpressionHandler expHandler = null;
164 try {
165 final Constructor<?> handlerCtor =
166 typeHandlers.get(ast.getType());
167 if (handlerCtor != null) {
168 expHandler = (ExpressionHandler) handlerCtor.newInstance(
169 indentCheck, ast, parent);
170 }
171 }
172
173 catch (final InstantiationException e) {
174 LOG.debug("couldn't instantiate constructor for " + ast, e);
175 throw new RuntimeException("couldn't instantiate constructor for "
176 + ast);
177 }
178 catch (final IllegalAccessException e) {
179 LOG.debug("couldn't access constructor for " + ast, e);
180 throw new RuntimeException("couldn't access constructor for "
181 + ast);
182 }
183 catch (final InvocationTargetException e) {
184 LOG.debug("couldn't instantiate constructor for " + ast, e);
185 throw new RuntimeException("couldn't instantiate constructor for "
186 + ast);
187 }
188 if (expHandler == null) {
189 throw new RuntimeException("no handler for type " + ast.getType());
190 }
191
192 return expHandler;
193 }
194
195
196
197
198
199
200
201
202
203
204 ExpressionHandler createMethodCallHandler(IndentationCheck indentCheck,
205 DetailAST ast, ExpressionHandler parent)
206 {
207 ExpressionHandler theParent = parent;
208 DetailAST astNode = ast.getFirstChild();
209 while (astNode != null && astNode.getType() == TokenTypes.DOT) {
210 astNode = astNode.getFirstChild();
211 }
212 if (astNode != null && isHandledType(astNode.getType())) {
213 theParent = getHandler(indentCheck, astNode, theParent);
214 createdHandlers.put(astNode, theParent);
215 }
216 return new MethodCallHandler(indentCheck, ast, theParent);
217 }
218
219
220 void clearCreatedHandlers()
221 {
222 createdHandlers.clear();
223 }
224
225
226 private final Map<DetailAST, ExpressionHandler> createdHandlers =
227 Maps.newHashMap();
228 }