KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > j2me > bloat > RegistryEnhancer


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.j2me.bloat;
22
23 import java.lang.reflect.*;
24 import java.util.*;
25
26 import EDU.purdue.cs.bloat.editor.*;
27 import EDU.purdue.cs.bloat.editor.Type;
28 import EDU.purdue.cs.bloat.file.*;
29 import EDU.purdue.cs.bloat.reflect.*;
30 import EDU.purdue.cs.bloat.reflect.FieldInfo;
31
32 import com.db4o.reflect.self.*;
33 import com.db4o.reflect.self.ClassInfo;
34
35 public class RegistryEnhancer {
36     private static final String JavaDoc COMPONENTTYPE_METHODNAME = "componentType";
37
38     private static final String JavaDoc ARRAYFOR_METHODNAME = "arrayFor";
39
40     private static final String JavaDoc INFOFOR_METHODNAME = "infoFor";
41
42     private static final String JavaDoc CLASSINFO_CONSTNAME = "CLASSINFO";
43
44     private ClassEditor _ce;
45
46     private Class JavaDoc[] _clazzes;
47
48     private BloatContext _context;
49
50     public RegistryEnhancer(BloatContext context, ClassEditor ce, Class JavaDoc clazz) {
51         this._ce = ce;
52         this._clazzes = createClasses(clazz);
53         this._context = context;
54     }
55
56     private static Class JavaDoc[] createClasses(Class JavaDoc concrete) {
57         List list = new ArrayList();
58         Class JavaDoc cur = concrete;
59         while (cur != Object JavaDoc.class) {
60             list.add(cur);
61             cur = cur.getSuperclass();
62         }
63         return (Class JavaDoc[]) list.toArray(new Class JavaDoc[list.size()]);
64     }
65
66     public void generate() {
67         _context.addNoArgConstructor(_ce);
68         generateCLASSINFOField();
69         generateInfoForMethod();
70         generateArrayForMethod();
71         generateComponentTypeMethod();
72     }
73
74     private void generateCLASSINFOField() {
75         FieldEditor fe = _context.createField(_ce, 26, Type
76                 .getType(Hashtable.class), CLASSINFO_CONSTNAME);
77
78         MethodBuilder builder = new MethodBuilder(_context, _ce,
79                 Modifiers.STATIC, void.class, "<clinit>", new Class JavaDoc[0],
80                 new Class JavaDoc[0]);
81         builder.newRef(Hashtable.class);
82         builder.dup();
83         builder.invokeSpecial(_context.getType(Hashtable.class), BloatContext.INIT_METHODNAME,
84                 new Type[0], Type.VOID);
85         builder.putstatic(_ce.type(), Hashtable.class, CLASSINFO_CONSTNAME);
86         for (int classIdx = 0; classIdx < _clazzes.length; classIdx++) {
87             builder.getstatic(_ce.type(), Hashtable.class, CLASSINFO_CONSTNAME);
88             generateInfoForClass(builder, _clazzes[classIdx]);
89         }
90
91         builder.returnInstruction();
92         builder.commit();
93         fe.commit();
94
95     }
96
97     private void generateInfoForClass(MethodBuilder builder, Class JavaDoc clazz) {
98         builder.invokeLoadClassConstMethod(clazz);
99         builder.newRef(com.db4o.reflect.self.ClassInfo.class);
100         builder.dup();
101         FieldInfo[] fieldsInf = collectFieldsOfClass(clazz);
102         builder.ldc(isAbstractClass(clazz));
103         builder.invokeLoadClassConstMethod(clazz
104                 .getSuperclass());
105         builder.ldc(fieldsInf.length);
106         builder.anewarray(com.db4o.reflect.self.FieldInfo.class);
107         for (int i = 0; i < fieldsInf.length; i++) {
108             generateInfoForField(builder, _context.fieldEditor(clazz, fieldsInf[i]), i);
109         }
110         builder.invokeSpecial(_context.getType(ClassInfo.class), BloatContext.INIT_METHODNAME,
111                 new Type[] { Type.BOOLEAN, Type.CLASS,
112                         _context.getType(com.db4o.reflect.self.FieldInfo[].class) },
113                 Type.VOID);
114         builder.invokeVirtual(_context.getType(Hashtable.class), "put",
115                 new Type[] { Type.OBJECT, Type.OBJECT }, Type.OBJECT);
116     }
117
118     private void generateInfoForField(MethodBuilder builder, FieldEditor fieldEditor, int arrIdx) {
119         builder.dup();
120         builder.ldc(arrIdx);
121         builder.newRef(com.db4o.reflect.self.FieldInfo.class);
122         builder.dup();
123         builder.ldc(fieldEditor.name());
124         Class JavaDoc wrapper = PrimitiveUtil.wrapper(fieldEditor.type());
125         if (wrapper != null) {
126             builder.getstatic(wrapper, Class JavaDoc.class, "TYPE");
127         } else {
128             builder.invokeLoadClassConstMethod(fieldEditor.type().className());
129         }
130         builder.ldc(fieldEditor.isPublic());
131         builder.ldc(fieldEditor.isStatic());
132         builder.ldc(fieldEditor.isTransient());
133         builder.invokeSpecial(
134                 _context.getType(com.db4o.reflect.self.FieldInfo.class), BloatContext.INIT_METHODNAME,
135                 new Type[] { Type.STRING, Type.CLASS, Type.BOOLEAN,
136                         Type.BOOLEAN, Type.BOOLEAN }, Type.VOID);
137         builder.aastore();
138     }
139
140
141     private FieldInfo[] collectFieldsOfClass(Class JavaDoc clazz) {
142         ClassEditor ce = null;
143         FieldInfo[] fields = null;
144         try {
145             ce = new ClassEditor(null, new ClassFileLoader().loadClass(clazz
146                     .getName()));
147             fields = ce.fields();
148         } catch (ClassNotFoundException JavaDoc e) {
149             e.printStackTrace();
150         }
151         return fields;
152     }
153
154     private boolean isAbstractClass(Class JavaDoc clazz) {
155         return Modifier.isAbstract(clazz.getModifiers());
156     }
157
158     private void generateInfoForMethod() {
159         MethodBuilder builder = new MethodBuilder(_context, _ce,
160                 Modifiers.PUBLIC, com.db4o.reflect.self.ClassInfo.class,
161                 INFOFOR_METHODNAME, new Class JavaDoc[] { Class JavaDoc.class }, null);
162         builder.getstatic(_ce.type(), Hashtable.class, CLASSINFO_CONSTNAME);
163         builder.aload(1);
164         builder.invokeVirtual(_context.getType(Hashtable.class), "get",
165                 new Type[] { Type.OBJECT }, Type.OBJECT);
166         builder.checkcast(ClassInfo.class);
167         builder.areturn();
168         builder.commit();
169
170     }
171
172     private void generateArrayForMethod() {
173         MethodBuilder builder = new MethodBuilder(_context, _ce,
174                 Modifiers.PUBLIC, Object JavaDoc.class, ARRAYFOR_METHODNAME, new Class JavaDoc[] {
175                         Class JavaDoc.class, Integer.TYPE }, null);
176         int labelIdx = 1;
177         for (int classIdx = 0; classIdx < _clazzes.length; classIdx++) {
178             builder.invokeLoadClassConstMethod(_clazzes[classIdx]);
179             builder.aload(1);
180             builder.invokeVirtual(Type.CLASS,
181                     "isAssignableFrom", new Type[] { Type.CLASS },
182                     Type.BOOLEAN);
183             builder.ifeq(labelIdx);
184             builder.iload(2);
185             builder.newarray(_clazzes[classIdx]);
186             builder.areturn();
187             builder.label(labelIdx);
188             labelIdx++;
189         }
190         builder.aload(0);
191         builder.aload(1);
192         builder.iload(2);
193         builder.invokeSpecial(_context.getType(SelfReflectionRegistry.class),
194                 ARRAYFOR_METHODNAME, new Type[] { Type.CLASS, Type.INTEGER },
195                 Type.OBJECT);
196         builder.areturn();
197         builder.commit();
198     }
199
200     private void generateComponentTypeMethod() {
201         MethodBuilder builder = new MethodBuilder(_context, _ce,
202                 Modifiers.PUBLIC, Class JavaDoc.class, COMPONENTTYPE_METHODNAME,
203                 new Class JavaDoc[] { Class JavaDoc.class }, new Class JavaDoc[0]);
204         int labelId = 1;
205         for (int classIdx = 0; classIdx < _clazzes.length; classIdx++) {
206             builder
207                     .invokeLoadClassConstMethod(convertToArray(_clazzes[classIdx]));
208             builder.aload(1);
209             builder.invokeVirtual(Type.CLASS,
210                     "isAssignableFrom", new Type[] { Type.CLASS },
211                     Type.BOOLEAN);
212             builder.ifeq(labelId);
213             builder.invokeLoadClassConstMethod(_clazzes[classIdx]);
214             builder.areturn();
215             builder.label(labelId);
216             labelId++;
217         }
218         builder.aload(0);
219         builder.aload(1);
220         builder.invokeSpecial(
221                 _context.getType(com.db4o.reflect.self.SelfReflectionRegistry.class),
222                 COMPONENTTYPE_METHODNAME, new Type[] { Type.CLASS }, Type.CLASS);
223         builder.areturn();
224         builder.commit();
225
226     }
227
228     private Class JavaDoc convertToArray(Class JavaDoc clazz) {
229         return Array.newInstance(clazz, new int[1]).getClass();
230     }
231
232     
233     
234 }
235
Popular Tags