KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > ant > ClassSpecificationElement


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.ant;
22
23 import org.apache.tools.ant.*;
24 import org.apache.tools.ant.types.*;
25 import proguard.*;
26 import proguard.classfile.*;
27 import proguard.classfile.util.*;
28
29 import java.util.*;
30
31 /**
32  * This DataType represents a class specification in Ant.
33  *
34  * @author Eric Lafortune
35  */

36 public class ClassSpecificationElement extends DataType
37 {
38     private static final String JavaDoc ANY_CLASS_KEYWORD = "*";
39
40     private String JavaDoc access;
41     private String JavaDoc annotation;
42     private String JavaDoc type;
43     private String JavaDoc name;
44     private String JavaDoc extendsAnnotation;
45     private String JavaDoc extends_;
46     private List fieldSpecifications = new ArrayList();
47     private List methodSpecifications = new ArrayList();
48
49
50     /**
51      * Adds the contents of this class specification element to the given list.
52      * @param classSpecifications the class specifications to be extended.
53      */

54     public void appendTo(List classSpecifications)
55     {
56         // Get the referenced file set, or else this one.
57
ClassSpecificationElement classSpecificationElement = isReference() ?
58             (ClassSpecificationElement)getCheckedRef(this.getClass(),
59                                                      this.getClass().getName()) :
60             this;
61
62         ClassSpecification classSpecification =
63             createClassSpecification(classSpecificationElement);
64
65         // Add it to the list.
66
classSpecifications.add(classSpecification);
67     }
68
69
70     /**
71      * Creates a new class specification corresponding to the contents of this
72      * class specification element.
73      */

74     protected ClassSpecification createClassSpecification(ClassSpecificationElement classSpecificationElement)
75     {
76         String JavaDoc access = classSpecificationElement.access;
77         String JavaDoc annotation = classSpecificationElement.annotation;
78         String JavaDoc type = classSpecificationElement.type;
79         String JavaDoc name = classSpecificationElement.name;
80         String JavaDoc extendsAnnotation = classSpecificationElement.extendsAnnotation;
81         String JavaDoc extends_ = classSpecificationElement.extends_;
82
83         // For backward compatibility, allow a single "*" wildcard to match
84
// any class.
85
if (name != null &&
86             name.equals(ANY_CLASS_KEYWORD))
87         {
88             name = null;
89         }
90
91         ClassSpecification classSpecification =
92             new ClassSpecification(null,
93                                    requiredAccessFlags(true, access, type),
94                                    requiredAccessFlags(false, access, type),
95                                    annotation != null ? ClassUtil.internalType(annotation) : null,
96                                    name != null ? ClassUtil.internalClassName(name) : null,
97                                    extendsAnnotation != null ? ClassUtil.internalType(extendsAnnotation) : null,
98                                    extends_ != null ? ClassUtil.internalClassName(extends_) : null);
99
100         for (int index = 0; index < fieldSpecifications.size(); index++)
101         {
102             classSpecification.addField((MemberSpecification)fieldSpecifications.get(index));
103         }
104
105         for (int index = 0; index < methodSpecifications.size(); index++)
106         {
107             classSpecification.addMethod((MemberSpecification)methodSpecifications.get(index));
108         }
109
110         return classSpecification;
111     }
112
113
114     // Ant task attributes.
115

116     public void setAccess(String JavaDoc access)
117     {
118         this.access = access;
119     }
120
121
122     public void setAnnotation(String JavaDoc annotation)
123     {
124         this.annotation = annotation;
125     }
126
127
128     public void setType(String JavaDoc type)
129     {
130         this.type = type;
131     }
132
133
134     public void setName(String JavaDoc name)
135     {
136         this.name = name;
137     }
138
139
140     public void setExtendsannotation(String JavaDoc extendsAnnotation)
141     {
142         this.extendsAnnotation = extendsAnnotation;
143     }
144
145
146     public void setExtends(String JavaDoc extends_)
147     {
148         this.extends_ = extends_;
149     }
150
151
152     public void setImplements(String JavaDoc implements_)
153     {
154         this.extends_ = implements_;
155     }
156
157
158     // Ant task nested elements.
159

160     public void addConfiguredField(MemberSpecificationElement memberSpecificationElement)
161     {
162         if (fieldSpecifications == null)
163         {
164             fieldSpecifications = new ArrayList();
165         }
166
167         memberSpecificationElement.appendTo(fieldSpecifications,
168                                             false,
169                                             false);
170     }
171
172
173     public void addConfiguredMethod(MemberSpecificationElement memberSpecificationElement)
174     {
175         if (methodSpecifications == null)
176         {
177             methodSpecifications = new ArrayList();
178         }
179
180         memberSpecificationElement.appendTo(methodSpecifications,
181                                             true,
182                                             false);
183     }
184
185
186     public void addConfiguredConstructor(MemberSpecificationElement memberSpecificationElement)
187     {
188         if (methodSpecifications == null)
189         {
190             methodSpecifications = new ArrayList();
191         }
192
193         memberSpecificationElement.appendTo(methodSpecifications,
194                                             true,
195                                             true);
196     }
197
198
199     // Small utility methods.
200

201     private int requiredAccessFlags(boolean set,
202                                     String JavaDoc access,
203                                     String JavaDoc type)
204     throws BuildException
205     {
206         int accessFlags = 0;
207
208         if (access != null)
209         {
210             StringTokenizer tokenizer = new StringTokenizer(access, " ,");
211             while (tokenizer.hasMoreTokens())
212             {
213                 String JavaDoc token = tokenizer.nextToken();
214
215                 if (token.startsWith("!") ^ set)
216                 {
217                     String JavaDoc strippedToken = token.startsWith("!") ?
218                         token.substring(1) :
219                         token;
220
221                     int accessFlag =
222                         strippedToken.equals(ClassConstants.EXTERNAL_ACC_PUBLIC) ? ClassConstants.INTERNAL_ACC_PUBLIC :
223                         strippedToken.equals(ClassConstants.EXTERNAL_ACC_FINAL) ? ClassConstants.INTERNAL_ACC_FINAL :
224                         strippedToken.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
225                         0;
226
227                     if (accessFlag == 0)
228                     {
229                         throw new BuildException("Incorrect class access modifier ["+strippedToken+"]");
230                     }
231
232                     accessFlags |= accessFlag;
233                 }
234             }
235         }
236
237         if (type != null && (type.startsWith("!") ^ set))
238         {
239             int accessFlag =
240                 type.equals( ClassConstants.EXTERNAL_ACC_INTERFACE) ||
241                 type.equals("!" + ClassConstants.EXTERNAL_ACC_INTERFACE) ? ClassConstants.INTERNAL_ACC_INTERFACE :
242                 type.equals("class") ? 0 :
243                                                                            -1;
244             if (accessFlag == -1)
245             {
246                 throw new BuildException("Incorrect class type ["+type+"]");
247             }
248
249             accessFlags |= accessFlag;
250         }
251
252         return accessFlags;
253     }
254 }
255
Popular Tags