KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > gulden > util > javasource > Type


1 /*
2  * Project: BeautyJ - Customizable Java Source Code Transformer
3  * Class: de.gulden.util.javasource.Type
4  * Version: 1.1
5  *
6  * Date: 2004-09-29
7  *
8  * Note: Contains auto-generated Javadoc comments created by BeautyJ.
9  *
10  * This is licensed under the GNU General Public License (GPL)
11  * and comes with NO WARRANTY. See file license.txt for details.
12  *
13  * Author: Jens Gulden
14  * Email: beautyj@jensgulden.de
15  */

16
17 package de.gulden.util.javasource;
18
19 import de.gulden.util.javasource.jjt.Node;
20 import de.gulden.util.javasource.jjt.*;
21 import javax.xml.parsers.*;
22 import org.w3c.dom.*;
23 import java.io.*;
24 import java.util.*;
25
26 /**
27  * Represents a type.
28  *
29  * @author Jens Gulden
30  * @version 1.0
31  */

32 public class Type implements ParserTreeConstants, Serializable {
33
34     // ------------------------------------------------------------------------
35
// --- fields ---
36
// ------------------------------------------------------------------------
37

38     /**
39      * The type name.
40      */

41     protected String JavaDoc typeName;
42
43     /**
44      * The dimension.
45      */

46     protected int dimension;
47
48     /**
49      * The my member.
50      */

51     protected Member myMember;
52
53
54     // ------------------------------------------------------------------------
55
// --- constructor ---
56
// ------------------------------------------------------------------------
57

58     /**
59      * Creates a new instance of Type.
60      */

61     public Type(Member member) {
62         myMember=member;
63     }
64
65
66     // ------------------------------------------------------------------------
67
// --- methods ---
68
// ------------------------------------------------------------------------
69

70     /**
71      * Returns the unqualified type name.
72      */

73     public String JavaDoc getUnqualifiedTypeName() {
74         return SourceObject.unqualify(typeName, countOuterClasses(typeName));
75     }
76
77     /**
78      * Returns the type name.
79      */

80     public String JavaDoc getTypeName() {
81         return typeName;
82     }
83
84     /**
85      * Returns the full type name.
86      */

87     public String JavaDoc getFullTypeName() {
88         return getTypeName() + SourceParser.repeat("[]",dimension);
89     }
90
91     /**
92      * Returns the full type name.
93      */

94     public String JavaDoc getFullUnqualifiedTypeName() {
95         return getUnqualifiedTypeName() + SourceParser.repeat("[]",dimension);
96     }
97
98     /**
99      * Returns the dimension.
100      */

101     public int getDimension() {
102         return dimension;
103     }
104
105     /**
106      * Sets the type name.
107      */

108     public void setTypeName(String JavaDoc n) {
109         typeName=n;
110     }
111
112     /**
113      * Sets the dimension.
114      */

115     public void setDimension(int d) {
116         dimension=d;
117     }
118
119     /**
120      * Output this object as XML.
121      *
122      * @return The XML tag.
123      * @see #initFromXML
124      */

125     public Element buildXML(Document d) {
126         Element e=d.createElement("type");
127         String JavaDoc typeName=getTypeName();
128         e.setAttribute("name",typeName);
129         e.setAttribute("unqualifiedName",SourceObject.unqualify(typeName));
130         e.setAttribute("dimension",String.valueOf(getDimension()));
131         e.setAttribute("fullName",String.valueOf(getFullTypeName()));
132         return e;
133     }
134
135     /**
136      * Initialize this object from XML.
137      *
138      * @param element The XML tag.
139      * @throws IOException if an i/o error occurs
140      */

141     public void initFromXML(Element element) throws IOException {
142         String JavaDoc n=element.getAttribute("name");
143         String JavaDoc d=element.getAttribute("dimension");
144         if ((n!=null)&&(d!=null)) {
145             try {
146                 typeName=n;
147                 dimension=Integer.parseInt(d);
148             }
149             catch (NumberFormatException JavaDoc nfe) {
150                 throw new IOException("'<type>' tag must have numeric attribute 'dimension'");
151             }
152         }
153         else {
154             throw new IOException("'<type>' tag must have attribute 'qualifiedName'");
155         }
156     }
157
158     /**
159      * Initialize this object from parsed Java code.
160      * Special way of invoking.
161      *
162      * @param fathernode A father node from where array-declarators are recursively counted.
163      */

164     void initFromAST(Node fathernode) {
165         initFromAST(fathernode, null);
166     }
167
168     /**
169      * Initialize this object from parsed Java code.
170      * Special way of invoking.
171      *
172      * @param fathernode A father node from where array-declarators are recursively counted. May be null.
173      * @param varnode variable declarator node from where additional array-declarators are recursively counted. May be null.
174      */

175     void initFromAST(Node fathernode, Node varnode) {
176         Node typenode=fathernode.getChild(JJT_TYPE);
177         if (typenode.getChild(JJT_NAME)!=null) {
178             String JavaDoc n=typenode.getName();
179             typeName=myMember.getDeclaringClass().qualify(n);
180         } else {
181             typeName="void";
182         }
183         Node searchNode;
184         if (varnode != null) {
185             searchNode = typenode;
186         } else {
187             searchNode=fathernode;
188         }
189         dimension = countArrayDimension(searchNode);
190         if (varnode != null) {
191             dimension += countArrayDimension(varnode);
192         }
193     }
194
195     private int countOuterClasses(String JavaDoc classname) {
196         // is classname referencing source?
197
Package JavaDoc basePackage = myMember.getPackage().getBasePackage();
198         Class JavaDoc clazz = basePackage.findClass(classname);
199         if (clazz != null) { // yes, known from source
200
int cnt = 0;
201             while (clazz instanceof ClassInner) {
202                 cnt++;
203                 clazz = ((ClassInner)clazz).getDeclaringClass();
204             }
205             return cnt;
206         } else { // get from classpath
207
int cnt = 0;
208             boolean found = false;
209             do {
210                 try {
211                     //cl.loadClass(classname); // will fail if not inner class
212
java.lang.Class.forName(classname); // will throw exception if the name is a _valid_ inner class name, because inner classes must be seperated by '$' from their parents
213
found = true;
214                 } catch (ClassNotFoundException JavaDoc cnfe) {
215                     cnt++;
216                     // remove last component, until a non-inner class is reached
217
int pos = classname.lastIndexOf('.');
218                     if (pos == -1) { // should actually not happen as we assume parameter classname is aready qualified (and verified for existance by doing that)
219
return 0;
220                     }
221                     classname = classname.substring(0, pos);
222                 }
223             } while(!found);
224             return cnt;
225         }
226     }
227
228
229     // ------------------------------------------------------------------------
230
// --- static method ---
231
// ------------------------------------------------------------------------
232

233     /**
234      * Traverse through sub-tree and count occurrences of _ISARRAY-node.
235      */

236     private static int countArrayDimension(Node n) {
237         if (n.getId()==JJT_ISARRAY) {
238             return 1;
239         } else if (n.getId()==JJT_CODE) {
240             return 0; // do not recurse into code-section
241
} else {
242             int sum=0;
243             Node[] children=n.getAllChildren();
244             for (int i=0;i<children.length;i++) {
245                 Node child = children[i];
246                 if ( child.getId()!=JJT_PARAMETER ) { // don't recurse into parameter (if n if JJT_METHOD), testing here allows still the first call with n.getId()==JJT_PARAMETER when parsing parameters
247
sum+=countArrayDimension(children[i]); // recursion
248
}
249             }
250             return sum;
251         }
252     }
253
254 } // end Type
255
Popular Tags