1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.classfile.attribute.visitor;
22
23import proguard.classfile.*;
24import proguard.classfile.attribute.*;
25import proguard.classfile.attribute.annotation.*;
26import proguard.classfile.attribute.preverification.*;
27import proguard.util.*;
28
29import java.util.List;
30
31/**
32 * This AttributeVisitor delegates its visits another AttributeVisitor, but
33 * only when the visited attribute has a name that that matches a given regular
34 * expression.
35 *
36 * @author Eric Lafortune
37 */
38public class AttributeNameFilter
39implements   AttributeVisitor
40{
41    private final StringMatcher    regularExpressionMatcher;
42    private final AttributeVisitor attributeVisitor;
43
44
45    /**
46     * Creates a new AttributeNameFilter.
47     * @param regularExpression the regular expression against which attribute
48     *                          names will be matched.
49     * @param attributeVisitor  the <code>AttributeVisitor</code> to which
50     *                          visits will be delegated.
51     */
52    public AttributeNameFilter(String           regularExpression,
53                               AttributeVisitor attributeVisitor)
54    {
55        this(new ListParser(new NameParser()).parse(regularExpression),
56             attributeVisitor);
57    }
58
59
60    /**
61     * Creates a new AttributeNameFilter.
62     * @param regularExpression the regular expression against which attribute
63     *                          names will be matched.
64     * @param attributeVisitor  the <code>AttributeVisitor</code> to which
65     *                          visits will be delegated.
66     */
67    public AttributeNameFilter(List             regularExpression,
68                               AttributeVisitor attributeVisitor)
69    {
70        this(new ListParser(new NameParser()).parse(regularExpression),
71             attributeVisitor);
72    }
73
74
75    /**
76     * Creates a new AttributeNameFilter.
77     * @param regularExpressionMatcher the string matcher against which
78     *                                 attribute names will be matched.
79     * @param attributeVisitor         the <code>AttributeVisitor</code> to
80     *                                 which visits will be delegated.
81     */
82    public AttributeNameFilter(StringMatcher    regularExpressionMatcher,
83                               AttributeVisitor attributeVisitor)
84    {
85        this.regularExpressionMatcher = regularExpressionMatcher;
86        this.attributeVisitor         = attributeVisitor;
87    }
88
89
90    // Implementations for AttributeVisitor.
91
92    public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
93    {
94        if (accepted(clazz, unknownAttribute))
95        {
96            unknownAttribute.accept(clazz, attributeVisitor);
97        }
98    }
99
100
101    public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
102    {
103        if (accepted(clazz, bootstrapMethodsAttribute))
104        {
105            bootstrapMethodsAttribute.accept(clazz, attributeVisitor);
106        }
107    }
108
109
110    public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
111    {
112        if (accepted(clazz, sourceFileAttribute))
113        {
114            sourceFileAttribute.accept(clazz, attributeVisitor);
115        }
116    }
117
118
119    public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
120    {
121        if (accepted(clazz, sourceDirAttribute))
122        {
123            sourceDirAttribute.accept(clazz, attributeVisitor);
124        }
125    }
126
127
128    public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
129    {
130        if (accepted(clazz, innerClassesAttribute))
131        {
132            innerClassesAttribute.accept(clazz, attributeVisitor);
133        }
134    }
135
136
137    public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
138    {
139        if (accepted(clazz, enclosingMethodAttribute))
140        {
141            enclosingMethodAttribute.accept(clazz, attributeVisitor);
142        }
143    }
144
145
146    public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
147    {
148        if (accepted(clazz, deprecatedAttribute))
149        {
150            deprecatedAttribute.accept(clazz, attributeVisitor);
151        }
152    }
153
154
155    public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
156    {
157        if (accepted(clazz, deprecatedAttribute))
158        {
159            deprecatedAttribute.accept(clazz, field, attributeVisitor);
160        }
161    }
162
163
164    public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
165    {
166        if (accepted(clazz, deprecatedAttribute))
167        {
168            deprecatedAttribute.accept(clazz, method, attributeVisitor);
169        }
170    }
171
172
173    public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
174    {
175        if (accepted(clazz, syntheticAttribute))
176        {
177            syntheticAttribute.accept(clazz, attributeVisitor);
178        }
179    }
180
181
182    public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
183    {
184        if (accepted(clazz, syntheticAttribute))
185        {
186            syntheticAttribute.accept(clazz, field, attributeVisitor);
187        }
188    }
189
190
191    public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
192    {
193        if (accepted(clazz, syntheticAttribute))
194        {
195            syntheticAttribute.accept(clazz, method, attributeVisitor);
196        }
197    }
198
199
200    public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
201    {
202        if (accepted(clazz, signatureAttribute))
203        {
204            signatureAttribute.accept(clazz, attributeVisitor);
205        }
206    }
207
208
209    public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute)
210    {
211        if (accepted(clazz, signatureAttribute))
212        {
213            signatureAttribute.accept(clazz, field, attributeVisitor);
214        }
215    }
216
217
218    public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
219    {
220        if (accepted(clazz, signatureAttribute))
221        {
222            signatureAttribute.accept(clazz, method, attributeVisitor);
223        }
224    }
225
226
227    public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
228    {
229        if (accepted(clazz, constantValueAttribute))
230        {
231            constantValueAttribute.accept(clazz, field, attributeVisitor);
232        }
233    }
234
235
236    public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
237    {
238        if (accepted(clazz, exceptionsAttribute))
239        {
240            exceptionsAttribute.accept(clazz, method, attributeVisitor);
241        }
242    }
243
244
245    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
246    {
247        if (accepted(clazz, codeAttribute))
248        {
249            codeAttribute.accept(clazz, method, attributeVisitor);
250        }
251    }
252
253
254    public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
255    {
256        if (accepted(clazz, stackMapAttribute))
257        {
258            stackMapAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
259        }
260    }
261
262
263    public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
264    {
265        if (accepted(clazz, stackMapTableAttribute))
266        {
267            stackMapTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
268        }
269    }
270
271
272    public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
273    {
274        if (accepted(clazz, lineNumberTableAttribute))
275        {
276            lineNumberTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
277        }
278    }
279
280
281    public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
282    {
283        if (accepted(clazz, localVariableTableAttribute))
284        {
285            localVariableTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
286        }
287    }
288
289
290    public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
291    {
292        if (accepted(clazz, localVariableTypeTableAttribute))
293        {
294            localVariableTypeTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
295        }
296    }
297
298
299    public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
300    {
301        if (accepted(clazz, runtimeVisibleAnnotationsAttribute))
302        {
303            runtimeVisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
304        }
305    }
306
307
308    public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
309    {
310        if (accepted(clazz, runtimeVisibleAnnotationsAttribute))
311        {
312            runtimeVisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
313        }
314    }
315
316
317    public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
318    {
319        if (accepted(clazz, runtimeVisibleAnnotationsAttribute))
320        {
321            runtimeVisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
322        }
323    }
324
325
326    public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
327    {
328        if (accepted(clazz, runtimeInvisibleAnnotationsAttribute))
329        {
330            runtimeInvisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
331        }
332    }
333
334
335    public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
336    {
337        if (accepted(clazz, runtimeInvisibleAnnotationsAttribute))
338        {
339            runtimeInvisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
340        }
341    }
342
343
344    public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
345    {
346        if (accepted(clazz, runtimeInvisibleAnnotationsAttribute))
347        {
348            runtimeInvisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
349        }
350    }
351
352
353    public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
354    {
355        if (accepted(clazz, runtimeVisibleParameterAnnotationsAttribute))
356        {
357            runtimeVisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
358        }
359    }
360
361
362    public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
363    {
364        if (accepted(clazz, runtimeInvisibleParameterAnnotationsAttribute))
365        {
366            runtimeInvisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
367        }
368    }
369
370
371    public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
372    {
373        if (accepted(clazz, annotationDefaultAttribute))
374        {
375            annotationDefaultAttribute.accept(clazz, method, attributeVisitor);
376        }
377    }
378
379
380    // Small utility methods.
381
382    private boolean accepted(Clazz clazz, Attribute attribute)
383    {
384        return regularExpressionMatcher.matches(attribute.getAttributeName(clazz));
385    }
386}
387