KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > services > classfile > ClassEnumeration


1 /*
2
3    Derby - Class org.apache.derby.iapi.services.classfile.ClassEnumeration
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.services.classfile;
23
24 import java.util.Enumeration JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27 import org.apache.derby.iapi.services.classfile.VMDescriptor;
28
29 /**
30     An enumeration that filters only classes
31     from the enumeration of the class pool.
32
33     Code has been added to also include classes referenced in method and
34     field signatures.
35 */

36
37
38 class ClassEnumeration implements Enumeration JavaDoc {
39     ClassHolder cpt;
40     Enumeration JavaDoc inner;
41     CONSTANT_Index_info position;
42     HashSet JavaDoc foundClasses;
43     Enumeration JavaDoc classList;
44
45     ClassEnumeration( ClassHolder cpt,
46                         Enumeration JavaDoc e,
47                         Enumeration JavaDoc methods,
48                         Enumeration JavaDoc fields)
49     {
50         this.cpt = cpt;
51         inner = e;
52         foundClasses = new HashSet JavaDoc(30, 0.8f);
53         findMethodReferences(methods, foundClasses);
54         findFieldReferences(fields, foundClasses);
55         findClassReferences(foundClasses);
56         classList = java.util.Collections.enumeration(foundClasses);
57
58     }
59
60     public boolean hasMoreElements() {
61         return classList.hasMoreElements();
62     }
63
64     // uses cpt and inner
65
private void findClassReferences(HashSet JavaDoc foundClasses)
66     {
67
68         ConstantPoolEntry item;
69         CONSTANT_Index_info ref;
70
71
72         while (inner.hasMoreElements())
73         {
74             item = (ConstantPoolEntry) inner.nextElement();
75             if (item == null)
76                 continue;
77             if (item.getTag() == VMDescriptor.CONSTANT_Class)
78             {
79                 ref = (CONSTANT_Index_info) item;
80
81                 String JavaDoc className = cpt.className(ref.getIndex());
82
83                 // if this is an array type, distillClasses can
84
// handle it
85
if (className.startsWith("["))
86                 {
87                    distillClasses(className, foundClasses);
88                    continue;
89                 }
90
91                 // now we've got either a primitive type or a classname
92
// primitive types are all a single char
93

94                 if (className.length() > 1)
95                 {
96                     //we've got a class
97
if (className.startsWith("java"))
98                     {
99                         //skip it
100
continue;
101                     }
102
103                     foundClasses.add(className);
104                 }
105             }
106         }
107
108     }
109
110     private void findMethodReferences( Enumeration JavaDoc methods,
111                                         HashSet JavaDoc foundClasses)
112     {
113         while (methods.hasMoreElements())
114         {
115             ClassMember member = (ClassMember) methods.nextElement();
116             String JavaDoc description = member.getDescriptor();
117             distillClasses(description, foundClasses);
118         }
119     }
120
121     private void findFieldReferences( Enumeration JavaDoc fields,
122                                         HashSet JavaDoc foundClasses)
123     {
124         while (fields.hasMoreElements())
125         {
126             ClassMember member = (ClassMember) fields.nextElement();
127             String JavaDoc description = member.getDescriptor();
128             distillClasses(description, foundClasses);
129         }
130     }
131
132     void distillClasses(String JavaDoc fieldOrMethodSig, HashSet JavaDoc foundClasses)
133     {
134         if (fieldOrMethodSig == null || fieldOrMethodSig.length() < 1)
135         {
136             //empty string
137
return;
138         }
139
140         if (fieldOrMethodSig.charAt(0) != '(')
141         {
142             // first time through, we're dealing with a field here
143
// otherwise, it is a token from a method signature
144

145             int classNameStart = fieldOrMethodSig.indexOf('L');
146
147             if (classNameStart == -1)
148             {
149                 // no class in the type, so stop
150
return;
151             }
152
153             // chop off any leading ['s or other Java-primitive type
154
// signifiers (like I or L) *AND* substitute the dots
155
String JavaDoc fieldType =
156                 fieldOrMethodSig.substring(classNameStart + 1).replace('/', '.');
157
158             // we have to check for the semi-colon in case we are
159
// actually looking at a token from a method signature
160
if (fieldType.endsWith(";"))
161             {
162                 fieldType = fieldType.substring(0,fieldType.length()-1);
163             }
164
165             if (fieldType.startsWith("java"))
166             {
167                 return; // it's a java base class and we don't care about
168
// that either
169
}
170
171             foundClasses.add(fieldType);
172             return;
173          }
174          else
175          {
176             // it's a method signature
177
StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(fieldOrMethodSig, "();[");
178             while (tokens.hasMoreElements())
179             {
180                 String JavaDoc aToken = (String JavaDoc) tokens.nextToken();
181                 // because of the semi-colon delimiter in the tokenizer, we
182
// can have only one class name per token and it must be the
183
// last item in the token
184
int classNameStart = aToken.indexOf('L');
185                 if (classNameStart != -1)
186                 {
187                     distillClasses(aToken, foundClasses);
188                 }
189                 else
190                 {
191                     continue;
192                 }
193             }
194          }
195      }
196
197     public Object JavaDoc nextElement() {
198         return classList.nextElement();
199     }
200
201 }
202
Popular Tags