KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > speedo > generation > enhancer > JDOImplRegistrationAdder


1 /**
2  * Copyright (C) 2001-2004 France Telecom R&D
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */

18 package org.objectweb.speedo.generation.enhancer;
19
20 import org.objectweb.asm.Attribute;
21 import org.objectweb.asm.ClassVisitor;
22 import org.objectweb.asm.CodeVisitor;
23 import org.objectweb.asm.Constants;
24 import org.objectweb.asm.Label;
25 import org.objectweb.speedo.generation.lib.NamingRules;
26 import org.objectweb.speedo.metadata.SpeedoClass;
27 import org.objectweb.speedo.tools.StringReplace;
28 import org.objectweb.util.monolog.api.BasicLevel;
29 import org.objectweb.util.monolog.api.Logger;
30
31 /**
32  * Add the registration to the JDOImplHelper in a static code area
33  *
34  * The added code use the class$(String)Class method and the field
35  * class$classname which can exist or not. Therefore they are added if they do
36  * not already exist.
37  *
38  * @author S.Chassande-Barrioz
39  */

40 public class JDOImplRegistrationAdder extends LoggedClassAdapter {
41
42     /**
43      * Class name of the current visited class (with slash separator)
44      */

45     String JavaDoc className;
46     
47     String JavaDoc homeClassName;
48
49
50     /**
51      * indicates if the field already exists in the current class
52      */

53     boolean clinitfound = false;
54
55     /**
56      * indicates if a static area class$classname already exists in the
57      * current class.
58      */

59     boolean classFieldfound = false;
60
61     /**
62      * indicates if the class$ method already exists in the current class
63      */

64     boolean classMethodfound = false;
65
66     /**
67      * is the name of the static field referencing the java.lang.Class of
68      * the current class.
69      */

70     private String JavaDoc fieldName;
71     
72     private SpeedoClass sc;
73
74     public JDOImplRegistrationAdder(ClassVisitor classVisitor) {
75         super(classVisitor);
76     }
77
78     public JDOImplRegistrationAdder(ClassVisitor classVisitor, SpeedoClass sc, Logger logger) {
79         super(classVisitor, logger);
80         this.sc = sc;
81     }
82
83     public void visit(final int version, final int access,
84                       final String JavaDoc name,
85                       final String JavaDoc superName,
86                       final String JavaDoc[] interfaces,
87                       final String JavaDoc sourceFile) {
88         className = name;
89         homeClassName = NamingRules.homeName(name);
90         fieldName = "class$" + className.replace('/', '$');
91         super.visit(version, access, name, superName, interfaces, sourceFile);
92         logger.log(BasicLevel.DEBUG, "Class name: " + className);
93     }
94
95     public void visitField(int i, String JavaDoc s, String JavaDoc s1, Object JavaDoc o, Attribute attribute) {
96         super.visitField(i, s, s1, o, attribute);
97         classFieldfound |= s.equals(fieldName);
98     }
99
100     public CodeVisitor visitMethod(final int access,
101                                    final String JavaDoc name,
102                                    final String JavaDoc desc,
103                                    final String JavaDoc[] exceptions,
104                                    final Attribute attrs) {
105         CodeVisitor c = cv.visitMethod(access, name, desc, exceptions, attrs);
106         if (name.equals("<clinit>")) {
107             clinitfound = true;
108             addClassRegistrationCode(c);
109         } else if (name.equals("class$")) {
110             classMethodfound = true;
111         }
112         return c;
113     }
114
115     public void visitEnd() {
116         if (!clinitfound) {
117             logger.log(BasicLevel.DEBUG, "Adding static area in " + className);
118             CodeVisitor c = cv.visitMethod(Constants.ACC_STATIC,
119                 "<clinit>", "()V", null, null);
120             addClassRegistrationCode(c);
121             c.visitInsn(RETURN);
122             c.visitMaxs(0, 0);
123         }
124
125         if (!classMethodfound) {
126             logger.log(BasicLevel.DEBUG, "Adding static method class$(String)Class in " + className);
127             CodeVisitor c = cv.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$",
128                 "(Ljava/lang/String;)Ljava/lang/Class;", null, null);
129             Label l0 = new Label();
130             c.visitLabel(l0);
131             c.visitVarInsn(ALOAD, 0);
132             c.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName",
133                 "(Ljava/lang/String;)Ljava/lang/Class;");
134             Label l1 = new Label();
135             c.visitLabel(l1);
136             c.visitInsn(ARETURN);
137             Label l2 = new Label();
138             c.visitLabel(l2);
139             c.visitVarInsn(ASTORE, 1);
140             c.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError");
141             c.visitInsn(DUP);
142             c.visitVarInsn(ALOAD, 1);
143             c.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException",
144                 "getMessage", "()Ljava/lang/String;");
145             c.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError",
146                 "<init>", "(Ljava/lang/String;)V");
147             c.visitInsn(ATHROW);
148             c.visitTryCatchBlock(l0, l1, l2, "java/lang/ClassNotFoundException");
149             c.visitMaxs(3, 2);
150         }
151         if (!classFieldfound) {
152             logger.log(BasicLevel.DEBUG, "Adding static field class$ in " + className);
153             cv.visitField(ACC_STATIC + ACC_SYNTHETIC, fieldName,
154                 "Ljava/lang/Class;", null, null);
155         }
156
157         super.visitEnd();
158     }
159     
160     /**
161      * Add registration code of the class into the JDOImplHelper
162      * @param c
163      */

164     private void addClassRegistrationCode(CodeVisitor c) {
165         //Class thepc
166
c.visitFieldInsn(Constants.GETSTATIC,
167             className,
168             fieldName,
169             "Ljava/lang/Class;");
170
171         Label l1 = new Label();
172         c.visitJumpInsn(Constants.IFNONNULL, l1);
173         c.visitLdcInsn(StringReplace.replaceChar('/', '.', className));
174         c.visitMethodInsn(Constants.INVOKESTATIC, className, "class$",
175                 "(Ljava/lang/String;)Ljava/lang/Class;");
176         c.visitInsn(Constants.DUP);
177         c.visitFieldInsn(Constants.PUTSTATIC,
178             className,
179             fieldName,
180             "Ljava/lang/Class;");
181         Label l2 = new Label();
182         c.visitJumpInsn(Constants.GOTO, l2);
183         c.visitLabel(l1);
184         c.visitFieldInsn(Constants.GETSTATIC,
185             className,
186             fieldName,
187             "Ljava/lang/Class;");
188         c.visitLabel(l2);
189         //String[] field names
190
c.visitFieldInsn(GETSTATIC, homeClassName, "FIELD_NAMES", "[Ljava/lang/String;");
191         //Class[] fieldTypes
192
c.visitFieldInsn(GETSTATIC, homeClassName, "FIELD_TYPES", "[Ljava/lang/Class;");
193         //byte[] fieldFlags
194
c.visitFieldInsn(GETSTATIC, homeClassName, "FIELD_FLAGS", "[B");
195         //Class superClass
196
c.visitFieldInsn(GETSTATIC, homeClassName, "SUPER_CLASS", "Ljava/lang/Class;");
197         //PersistentCapable
198
c.visitInsn(ACONST_NULL);
199         c.visitMethodInsn(Constants.INVOKESTATIC,
200             "javax/jdo/spi/JDOImplHelper",
201             "registerClass",
202             "(Ljava/lang/Class;[Ljava/lang/String;[Ljava/lang/Class;[BLjava/lang/Class;Ljavax/jdo/spi/PersistenceCapable;)V");
203     }
204 }
205
Popular Tags