• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 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;
22 
23 import java.util.*;
24 
25 /**
26  * This class stores a specification of classes and possibly class members.
27  * The specification is template-based: the class names and class member names
28  * and descriptors can contain wildcards. Classes can be specified explicitly,
29  * or as extensions or implementations in the class hierarchy.
30  *
31  * @author Eric Lafortune
32  */
33 public class ClassSpecification implements Cloneable
34 {
35     public final String comments;
36     public       int    requiredSetAccessFlags;
37     public       int    requiredUnsetAccessFlags;
38     public final String annotationType;
39     public       String className;
40     public final String extendsAnnotationType;
41     public final String extendsClassName;
42 
43     public       List   fieldSpecifications;
44     public       List   methodSpecifications;
45 
46 
47     /**
48      * Creates a new ClassSpecification for all possible classes, without
49      * comments or class members.
50      */
ClassSpecification()51     public ClassSpecification()
52     {
53         this(null,
54              0,
55              0,
56              null,
57              null,
58              null,
59              null);
60     }
61 
62 
63     /**
64      * Creates a new ClassSpecification that is a copy of the given specification.
65      */
ClassSpecification(ClassSpecification classSpecification)66     public ClassSpecification(ClassSpecification classSpecification)
67     {
68         this(classSpecification.comments,
69              classSpecification.requiredSetAccessFlags,
70              classSpecification.requiredUnsetAccessFlags,
71              classSpecification.annotationType,
72              classSpecification.className,
73              classSpecification.extendsAnnotationType,
74              classSpecification.extendsClassName,
75              classSpecification.fieldSpecifications,
76              classSpecification.methodSpecifications);
77     }
78 
79 
80     /**
81      * Creates a new ClassSpecification for the specified class(es), without
82      * class members.
83      *
84      * @param comments                 provides optional comments on this
85      *                                 specification.
86      * @param requiredSetAccessFlags   the class access flags that must be set
87      *                                 in order for the class to apply.
88      * @param requiredUnsetAccessFlags the class access flags that must be
89      *                                 unset in order for the class to apply.
90      * @param annotationType           the name of the class that must be an
91      *                                 annotation of the class in order for it
92      *                                 to apply. The name may be null to
93      *                                 specify that no annotation is required.
94      * @param className                the class name. The name may be null to
95      *                                 specify any class, or it may contain
96      *                                 "**", "*", or "?" wildcards.
97      * @param extendsAnnotationType    the name of the class of that must be
98      *                                 an annotation of the class that the
99      *                                 class must extend or implement in order
100      *                                 to apply. The name may be null to
101      *                                 specify that no annotation is required.
102      * @param extendsClassName         the name of the class that the class
103      *                                 must extend or implement in order to
104      *                                 apply. The name may be null to specify
105      *                                 any class.
106      */
ClassSpecification(String comments, int requiredSetAccessFlags, int requiredUnsetAccessFlags, String annotationType, String className, String extendsAnnotationType, String extendsClassName)107     public ClassSpecification(String comments,
108                               int    requiredSetAccessFlags,
109                               int    requiredUnsetAccessFlags,
110                               String annotationType,
111                               String className,
112                               String extendsAnnotationType,
113                               String extendsClassName)
114     {
115         this(comments,
116              requiredSetAccessFlags,
117              requiredUnsetAccessFlags,
118              annotationType,
119              className,
120              extendsAnnotationType,
121              extendsClassName,
122              null,
123              null);
124     }
125 
126 
127     /**
128      * Creates a new ClassSpecification for the specified classes and class
129      * members.
130      *
131      * @param comments                 provides optional comments on this
132      *                                 specification.
133      * @param requiredSetAccessFlags   the class access flags that must be set
134      *                                 in order for the class to apply.
135      * @param requiredUnsetAccessFlags the class access flags that must be
136      *                                 unset in order for the class to apply.
137      * @param annotationType           the name of the class that must be an
138      *                                 annotation of the class in order for it
139      *                                 to apply. The name may be null to
140      *                                 specify that no annotation is required.
141      * @param className                the class name. The name may be null to
142      *                                 specify any class, or it may contain
143      *                                 "**", "*", or "?" wildcards.
144      * @param extendsAnnotationType    the name of the class of that must be
145      *                                 an annotation of the class that the
146      *                                 class must extend or implement in order
147      *                                 to apply. The name may be null to
148      *                                 specify that no annotation is required.
149      * @param extendsClassName         the name of the class that the class
150      *                                 must extend or implement in order to
151      *                                 apply. The name may be null to specify
152      *                                 any class.
153      * @param fieldSpecifications      the field specifications.
154      * @param methodSpecifications     the method specifications.
155      */
ClassSpecification(String comments, int requiredSetAccessFlags, int requiredUnsetAccessFlags, String annotationType, String className, String extendsAnnotationType, String extendsClassName, List fieldSpecifications, List methodSpecifications)156     public ClassSpecification(String comments,
157                               int    requiredSetAccessFlags,
158                               int    requiredUnsetAccessFlags,
159                               String annotationType,
160                               String className,
161                               String extendsAnnotationType,
162                               String extendsClassName,
163                               List   fieldSpecifications,
164                               List   methodSpecifications)
165     {
166         this.comments                 = comments;
167         this.requiredSetAccessFlags   = requiredSetAccessFlags;
168         this.requiredUnsetAccessFlags = requiredUnsetAccessFlags;
169         this.annotationType           = annotationType;
170         this.className                = className;
171         this.extendsAnnotationType    = extendsAnnotationType;
172         this.extendsClassName         = extendsClassName;
173         this.fieldSpecifications      = fieldSpecifications;
174         this.methodSpecifications     = methodSpecifications;
175     }
176 
177 
178     /**
179      * Specifies to keep the specified field(s) of this option's class(es).
180      *
181      * @param fieldSpecification the field specification.
182      */
addField(MemberSpecification fieldSpecification)183     public void addField(MemberSpecification fieldSpecification)
184     {
185         if (fieldSpecifications == null)
186         {
187             fieldSpecifications = new ArrayList();
188         }
189 
190         fieldSpecifications.add(fieldSpecification);
191     }
192 
193 
194     /**
195      * Specifies to keep the specified method(s) of this option's class(es).
196      *
197      * @param methodSpecification the method specification.
198      */
addMethod(MemberSpecification methodSpecification)199     public void addMethod(MemberSpecification methodSpecification)
200     {
201         if (methodSpecifications == null)
202         {
203             methodSpecifications = new ArrayList();
204         }
205 
206         methodSpecifications.add(methodSpecification);
207     }
208 
209 
210 
211     // Implementations for Object.
212 
equals(Object object)213     public boolean equals(Object object)
214     {
215         if (object == null ||
216             this.getClass() != object.getClass())
217         {
218             return false;
219         }
220 
221         ClassSpecification other = (ClassSpecification)object;
222         return
223 //          (this.comments                 == null ? other.comments              == null : this.comments.equals(other.comments)                          ) &&
224             (this.requiredSetAccessFlags   == other.requiredSetAccessFlags                                                                               ) &&
225             (this.requiredUnsetAccessFlags == other.requiredUnsetAccessFlags                                                                             ) &&
226             (this.annotationType           == null ? other.annotationType        == null : this.annotationType.equals(other.annotationType)              ) &&
227             (this.className                == null ? other.className             == null : this.className.equals(other.className)                        ) &&
228             (this.extendsAnnotationType    == null ? other.extendsAnnotationType == null : this.extendsAnnotationType.equals(other.extendsAnnotationType)) &&
229             (this.extendsClassName         == null ? other.extendsClassName      == null : this.extendsClassName.equals(other.extendsClassName)          ) &&
230             (this.fieldSpecifications      == null ? other.fieldSpecifications   == null : this.fieldSpecifications.equals(other.fieldSpecifications)    ) &&
231             (this.methodSpecifications     == null ? other.methodSpecifications  == null : this.methodSpecifications.equals(other.methodSpecifications)  );
232     }
233 
hashCode()234     public int hashCode()
235     {
236         return
237 //          (comments              == null ? 0 : comments.hashCode()             ) ^
238             (requiredSetAccessFlags                                              ) ^
239             (requiredUnsetAccessFlags                                            ) ^
240             (annotationType        == null ? 0 : annotationType.hashCode()       ) ^
241             (className             == null ? 0 : className.hashCode()            ) ^
242             (extendsAnnotationType == null ? 0 : extendsAnnotationType.hashCode()) ^
243             (extendsClassName      == null ? 0 : extendsClassName.hashCode()     ) ^
244             (fieldSpecifications   == null ? 0 : fieldSpecifications.hashCode()  ) ^
245             (methodSpecifications  == null ? 0 : methodSpecifications.hashCode() );
246     }
247 
clone()248     public Object clone()
249     {
250         try
251         {
252             return super.clone();
253         }
254         catch (CloneNotSupportedException e)
255         {
256             return null;
257         }
258     }
259 }
260