KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > obfuscate > AttributeUsageMarker


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 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  */

21 package proguard.obfuscate;
22
23 import proguard.classfile.*;
24 import proguard.classfile.attribute.*;
25 import proguard.classfile.attribute.annotation.*;
26 import proguard.classfile.attribute.preverification.*;
27 import proguard.classfile.attribute.visitor.AttributeVisitor;
28 import proguard.classfile.util.SimplifiedVisitor;
29 import proguard.classfile.visitor.*;
30 import proguard.util.*;
31
32 import java.util.List JavaDoc;
33
34
35 /**
36  * This ClassVisitor marks all attributes that should be kept in the classes
37  * it visits.
38  *
39  * @see AttributeShrinker
40  *
41  * @author Eric Lafortune
42  */

43 public class AttributeUsageMarker
44 extends SimplifiedVisitor
45 implements ClassVisitor,
46              MemberVisitor,
47              AttributeVisitor
48 {
49     // A visitor info flag to indicate the attribute is being used.
50
private static final Object JavaDoc USED = new Object JavaDoc();
51
52
53     // Flags to specify whether optional attributes should be kept anyway.
54
private boolean keepAllAttributes;
55     private boolean keepAllUnknownAttributes;
56     private boolean keepAllKnownAttributes;
57     private StringMatcher keepAttributes;
58
59     private boolean keepSourceFileAttribute;
60     private boolean keepSourceDirAttribute;
61     private boolean keepInnerClassesAttribute;
62     private boolean keepEnclosingMethodAttribute;
63     private boolean keepDeprecatedAttribute;
64     private boolean keepSyntheticAttribute;
65     private boolean keepSignatureAttribute;
66     private boolean keepExceptionsAttribute;
67     private boolean keepLineNumberTableAttribute;
68     private boolean keepLocalVariableTableAttribute;
69     private boolean keepLocalVariableTypeTableAttribute;
70     private boolean keepRuntimeVisibleAnnotationsAttribute;
71     private boolean keepRuntimeInvisibleAnnotationsAttribute;
72     private boolean keepRuntimeVisibleParameterAnnotationsAttribute;
73     private boolean keepRuntimeInvisibleParameterAnnotationsAttribute;
74     private boolean keepAnnotationDefaultAttribute;
75
76
77     /**
78      * Specifies to keep all optional attributes.
79      */

80     public void setKeepAllAttributes()
81     {
82         keepAllAttributes = true;
83     }
84
85     /**
86      * Specifies to keep all unknown attributes.
87      */

88     public void setKeepAllUnknownAttributes()
89     {
90         keepAllUnknownAttributes = true;
91     }
92
93     /**
94      * Specifies to keep all known attributes.
95      */

96     public void setKeepAllKnownAttributes()
97     {
98         keepAllKnownAttributes = true;
99     }
100
101
102     /**
103      * Specifies to keep optional attributes with the given names. The attribute
104      * names may contain "*" or "?" wildcards, and they may be preceded by the
105      * "!" negator.
106      */

107     public void setKeepAttributes(List JavaDoc attributeNames)
108     {
109         keepAttributes = new BasicListMatcher(attributeNames);
110
111         // Precompute whether the list of attribute names matches the supported
112
// attributes.
113
keepSourceFileAttribute = keepAttributes.matches(ClassConstants.ATTR_SourceFile);
114         keepSourceDirAttribute = keepAttributes.matches(ClassConstants.ATTR_SourceDir);
115         keepInnerClassesAttribute = keepAttributes.matches(ClassConstants.ATTR_InnerClasses);
116         keepEnclosingMethodAttribute = keepAttributes.matches(ClassConstants.ATTR_EnclosingMethod);
117         keepDeprecatedAttribute = keepAttributes.matches(ClassConstants.ATTR_Deprecated);
118         keepSyntheticAttribute = keepAttributes.matches(ClassConstants.ATTR_Synthetic);
119         keepSignatureAttribute = keepAttributes.matches(ClassConstants.ATTR_Signature);
120         keepExceptionsAttribute = keepAttributes.matches(ClassConstants.ATTR_Exceptions);
121         keepLineNumberTableAttribute = keepAttributes.matches(ClassConstants.ATTR_LineNumberTable);
122         keepLocalVariableTableAttribute = keepAttributes.matches(ClassConstants.ATTR_LocalVariableTable);
123         keepLocalVariableTypeTableAttribute = keepAttributes.matches(ClassConstants.ATTR_LocalVariableTypeTable);
124         keepRuntimeVisibleAnnotationsAttribute = keepAttributes.matches(ClassConstants.ATTR_RuntimeVisibleAnnotations);
125         keepRuntimeInvisibleAnnotationsAttribute = keepAttributes.matches(ClassConstants.ATTR_RuntimeInvisibleAnnotations);
126         keepRuntimeVisibleParameterAnnotationsAttribute = keepAttributes.matches(ClassConstants.ATTR_RuntimeVisibleParameterAnnotations);
127         keepRuntimeInvisibleParameterAnnotationsAttribute = keepAttributes.matches(ClassConstants.ATTR_RuntimeInvisibleParameterAnnotations);
128         keepAnnotationDefaultAttribute = keepAttributes.matches(ClassConstants.ATTR_AnnotationDefault);
129     }
130
131
132     // Implementations for ClassVisitor.
133

134     public void visitProgramClass(ProgramClass programClass)
135     {
136         // Mark the class member attributes that should be kept.
137
programClass.fieldsAccept(this);
138         programClass.methodsAccept(this);
139
140         // Mark the class attributes that should be kept.
141
programClass.attributesAccept(this);
142     }
143
144
145     // Implementations for MemberVisitor.
146

147     public void visitProgramField(ProgramClass programClass, ProgramField programField)
148     {
149         visitMember(programClass, programField);
150     }
151
152
153     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
154     {
155         visitMember(programClass, programMethod);
156     }
157
158
159     private void visitMember(ProgramClass programClass, ProgramMember programMember)
160     {
161         // Mark the class member attributes that should be kept.
162
programMember.attributesAccept(programClass, this);
163     }
164
165
166     // Implementations for AttributeVisitor.
167

168     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
169     {
170         if (keepAllAttributes ||
171             keepAllUnknownAttributes ||
172             (keepAttributes != null &&
173              keepAttributes.matches(unknownAttribute.getAttributeName(clazz))))
174         {
175             markAsUsed(unknownAttribute);
176         }
177     }
178
179
180     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
181     {
182         if (keepAllAttributes ||
183             keepAllKnownAttributes ||
184             keepSourceFileAttribute)
185         {
186             markAsUsed(sourceFileAttribute);
187         }
188     }
189
190
191     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
192     {
193         if (keepAllAttributes ||
194             keepAllKnownAttributes ||
195             keepSourceDirAttribute)
196         {
197             markAsUsed(sourceDirAttribute);
198         }
199     }
200
201
202     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
203     {
204         if (keepAllAttributes ||
205             keepAllKnownAttributes ||
206             keepInnerClassesAttribute)
207         {
208             markAsUsed(innerClassesAttribute);
209         }
210     }
211
212
213     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
214     {
215         if (keepAllAttributes ||
216             keepAllKnownAttributes ||
217             keepEnclosingMethodAttribute)
218         {
219             markAsUsed(enclosingMethodAttribute);
220         }
221     }
222
223
224     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
225     {
226         if (keepAllAttributes ||
227             keepAllKnownAttributes ||
228             keepDeprecatedAttribute)
229         {
230             markAsUsed(deprecatedAttribute);
231         }
232     }
233
234
235     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
236     {
237         if (keepAllAttributes ||
238             keepAllKnownAttributes ||
239             keepSyntheticAttribute)
240         {
241             markAsUsed(syntheticAttribute);
242         }
243     }
244
245
246     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
247     {
248         if (keepAllAttributes ||
249             keepAllKnownAttributes ||
250             keepSignatureAttribute)
251         {
252             markAsUsed(signatureAttribute);
253         }
254     }
255
256
257     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
258     {
259         markAsUsed(constantValueAttribute);
260     }
261
262
263     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
264     {
265         if (keepAllAttributes ||
266             keepAllKnownAttributes ||
267             keepExceptionsAttribute)
268         {
269             markAsUsed(exceptionsAttribute);
270         }
271     }
272
273
274     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
275     {
276         markAsUsed(codeAttribute);
277
278         // Mark the code attributes that should be kept.
279
codeAttribute.attributesAccept(clazz, method, this);
280     }
281
282
283     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
284     {
285         markAsUsed(stackMapAttribute);
286     }
287
288
289     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
290     {
291         markAsUsed(stackMapTableAttribute);
292     }
293
294
295     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
296     {
297         if (keepAllAttributes ||
298             keepAllKnownAttributes ||
299             keepLineNumberTableAttribute)
300         {
301             markAsUsed(lineNumberTableAttribute);
302         }
303     }
304
305
306     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
307     {
308         if (keepAllAttributes ||
309             keepAllKnownAttributes ||
310             keepLocalVariableTableAttribute)
311         {
312             markAsUsed(localVariableTableAttribute);
313         }
314     }
315
316
317     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
318     {
319         if (keepAllAttributes ||
320             keepAllKnownAttributes ||
321             keepLocalVariableTypeTableAttribute)
322         {
323             markAsUsed(localVariableTypeTableAttribute);
324         }
325     }
326
327
328     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
329     {
330         if (keepAllAttributes ||
331             keepAllKnownAttributes ||
332             keepRuntimeVisibleAnnotationsAttribute)
333         {
334             markAsUsed(runtimeVisibleAnnotationsAttribute);
335         }
336     }
337
338
339     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
340     {
341         if (keepAllAttributes ||
342             keepAllKnownAttributes ||
343             keepRuntimeInvisibleAnnotationsAttribute)
344         {
345             markAsUsed(runtimeInvisibleAnnotationsAttribute);
346         }
347     }
348
349
350     public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
351     {
352         if (keepAllAttributes ||
353             keepAllKnownAttributes ||
354             keepRuntimeVisibleParameterAnnotationsAttribute)
355         {
356             markAsUsed(runtimeVisibleParameterAnnotationsAttribute);
357         }
358     }
359
360
361     public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
362     {
363         if (keepAllAttributes ||
364             keepAllKnownAttributes ||
365             keepRuntimeInvisibleParameterAnnotationsAttribute)
366         {
367             markAsUsed(runtimeInvisibleParameterAnnotationsAttribute);
368         }
369     }
370
371
372     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
373     {
374         if (keepAllAttributes ||
375             keepAllKnownAttributes ||
376             keepAnnotationDefaultAttribute)
377         {
378             markAsUsed(annotationDefaultAttribute);
379         }
380     }
381
382
383     // Small utility methods.
384

385     /**
386      * Marks the given VisitorAccepter as being used (or useful).
387      * In this context, the VisitorAccepter will be an Attribute object.
388      */

389     private static void markAsUsed(VisitorAccepter visitorAccepter)
390     {
391         visitorAccepter.setVisitorInfo(USED);
392     }
393
394
395     /**
396      * Returns whether the given VisitorAccepter has been marked as being used.
397      * In this context, the VisitorAccepter will be an Attribute object.
398      */

399     static boolean isUsed(VisitorAccepter visitorAccepter)
400     {
401         return visitorAccepter.getVisitorInfo() == USED;
402     }
403 }
404
Popular Tags