KickJava   Java API By Example, From Geeks To Geeks.

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


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 EDU.purdue.cs.bloat.editor.*;
24 import EDU.purdue.cs.bloat.reflect.*;
25
26 import com.db4o.reflect.self.*;
27
28 public class ClassEnhancer {
29
30     private static final String JavaDoc SELFSET_METHODNAME = "self_set";
31
32     private static final String JavaDoc SELFGET_METHODNAME = "self_get";
33
34     private ClassEditor _ce;
35
36     private BloatContext _context;
37
38     public ClassEnhancer(BloatContext context, ClassEditor ce) {
39         this._context = context;
40         this._ce = ce;
41     }
42
43     public boolean inspectNoArgConstr(MethodInfo[] methods) {
44         MethodEditor me;
45         for (int i = 0; i < methods.length; i++) {
46             me = new MethodEditor(_ce, methods[i]);
47             if ((me.type().equals(Type.VOID))
48                     && (me.name().equals(BloatContext.INIT_METHODNAME))) {
49                 return true;
50             }
51         }
52         return false;
53     }
54
55     protected void generateSelf_get(MemberRef[] fields) {
56         MethodBuilder builder = new MethodBuilder(_context, _ce,
57                 Modifiers.PUBLIC, Object JavaDoc.class, SELFGET_METHODNAME,
58                 new Class JavaDoc[] { String JavaDoc.class },new Class JavaDoc[0]);
59
60         for (int fieldIdx = 0; fieldIdx < fields.length; fieldIdx++) {
61             generateSelfGetMethodCase(builder, fieldIdx, fields[fieldIdx]);
62         }
63         Type superType = _ce.superclass();
64         if (instrumentedType(superType)) {
65             builder.aload(0);
66             builder.aload(1);
67             builder.invokeSpecial(superType, SELFGET_METHODNAME,
68                     new Type[] { Type.STRING }, Type.OBJECT);
69         } else {
70             builder.ldc(null);
71         }
72         builder.areturn();
73         builder.commit();
74     }
75
76     private void generateSelfGetMethodCase(MethodBuilder builder, int labelIdx, MemberRef field) {
77         Class JavaDoc wrapper = null;
78         if (field.type().isPrimitive()) {
79             wrapper = PrimitiveUtil.wrapper(field.type());
80         }
81         builder.aload(1);
82         builder.ldc(field.name());
83         builder.invokeVirtual(Type.STRING, BloatContext.EQUALS_METHODNAME,
84                 new Type[] { Type.OBJECT }, Type.BOOLEAN);
85         builder.ifeq(labelIdx + 1);
86         if (wrapper != null) {
87             builder.newRef(wrapper);
88             builder.dup();
89         }
90         builder.aload(0);
91         builder.getfield(field);
92         if (wrapper != null) {
93             builder.invokeSpecial(_context
94                     .getType(wrapper), BloatContext.INIT_METHODNAME,
95                     new Type[] { field.type() }, Type.VOID);
96         }
97         builder.areturn();
98         builder.label(labelIdx + 1);
99     }
100
101     // TODO: Shouldn't this information be passed in by the calling class?
102
// (It should know which classes it instruments anyway.)
103
private boolean instrumentedType(Type type) {
104         String JavaDoc typeName = _context.normalizeClassName(type.className());
105         System.err.println(typeName);
106         return !(typeName.startsWith("java.") || typeName.startsWith("javax.") || typeName
107                 .startsWith("sun."));
108
109     }
110
111     protected void generateSelf_set(MemberRef[] fields) {
112         MethodBuilder builder = new MethodBuilder(_context, _ce,
113                 Modifiers.PUBLIC, Void.TYPE, SELFSET_METHODNAME, new Class JavaDoc[] {
114                         String JavaDoc.class, Object JavaDoc.class }, null);
115
116         for (int fieldIdx = 0; fieldIdx < fields.length; fieldIdx++) {
117             generateSelfSetFieldCase(builder, fieldIdx, fields[fieldIdx]);
118         }
119
120         Type superType = _ce.superclass();
121         if (instrumentedType(superType)) {
122             builder.aload(0);
123             builder.aload(1);
124             builder.aload(2);
125             builder.invokeSpecial(superType, SELFSET_METHODNAME,
126                     new Type[] { Type.STRING, Type.OBJECT }, Type.VOID);
127
128         } else {
129             builder.ldc(null);
130         }
131
132         builder.returnInstruction();
133         builder.commit();
134
135     }
136
137     private void generateSelfSetFieldCase(MethodBuilder builder, int labelIdx, MemberRef field) {
138         Type fieldType = field.type();
139
140         Class JavaDoc wrapper = PrimitiveUtil.wrapper(fieldType);
141         builder.aload(1);
142         builder.ldc(field.name());
143         builder.invokeVirtual(Type.STRING, BloatContext.EQUALS_METHODNAME,
144                 new Type[] { Type.OBJECT }, Type.BOOLEAN);
145         builder.ifeq(labelIdx + 1);
146         builder.aload(0);
147         builder.aload(2);
148         if (wrapper != null) {
149             builder.checkcast(wrapper);
150             builder.invokeVirtual(_context
151                     .getType(wrapper), PrimitiveUtil.conversionFunctionName(wrapper), new Type[0], fieldType);
152         } else {
153             builder.checkcast(fieldType);
154         }
155         builder.putfield(field);
156         builder.returnInstruction();
157         builder.label(labelIdx + 1);
158     }
159
160     public void generate() {
161         addInterfaceIfNeeded();
162         if (!(inspectNoArgConstr(_ce.methods()))) {
163             _context.addNoArgConstructor(_ce);
164         }
165         MemberRef[] declaredFields = _context.collectDeclaredFields(_ce);
166         generateSelf_get(declaredFields);
167         generateSelf_set(declaredFields);
168     }
169
170     private void addInterfaceIfNeeded() {
171         if(!instrumentedType(_ce.superclass())&&!implementsSelfReflectable(_ce)) {
172             _ce.addInterface(SelfReflectable.class);
173         }
174     }
175
176     private boolean implementsSelfReflectable(ClassEditor ce) {
177         Type[] interfaces = ce.interfaces();
178
179         for (int interfIdx = 0; interfIdx < interfaces.length; interfIdx++) {
180             if (interfaces[interfIdx].getClass().equals(SelfReflectable.class)) {
181                 return true;
182             }
183         }
184         return false;
185     }
186
187 }
188
Popular Tags