KickJava   Java API By Example, From Geeks To Geeks.

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


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.ClassVisitor;
21 import org.objectweb.asm.CodeVisitor;
22 import org.objectweb.asm.Constants;
23 import org.objectweb.asm.Type;
24 import org.objectweb.asm.Attribute;
25 import org.objectweb.speedo.metadata.SpeedoClass;
26 import org.objectweb.speedo.metadata.SpeedoField;
27 import org.objectweb.speedo.generation.lib.NamingRules;
28 import org.objectweb.speedo.naming.api.UserId;
29 import org.objectweb.util.monolog.api.Logger;
30 import org.objectweb.util.monolog.api.BasicLevel;
31
32 import java.util.Iterator JavaDoc;
33
34 /**
35  * It adds the implementation of the UserId and specific PNameGetter interfaces
36  * in the user identifier.
37  *
38  * @author S.Chassande-Barrioz
39  */

40 public class UserIdEnhancer extends LoggedClassAdapter {
41
42     protected SpeedoClass jdoClass;
43
44     public final static String JavaDoc ADDED_FIELD_NAME = "jdoPersistentClassName";
45     public final static String JavaDoc ADDED_FIELD_DESC = "Ljava/lang/String;";
46
47     private String JavaDoc className ;
48
49     public UserIdEnhancer(ClassVisitor classVisitor,
50                           SpeedoClass jdoClass,
51                           Logger logger) {
52         super(classVisitor, logger);
53         this.jdoClass = jdoClass;
54     }
55
56     public void visit(final int version, final int access,
57                       final String JavaDoc cn,
58                       final String JavaDoc superName,
59                       final String JavaDoc[] interfaces,
60                       final String JavaDoc sourceFile) {
61         className = cn;
62         String JavaDoc[] itfs;
63         String JavaDoc pngcn = NamingRules.pngName(jdoClass.objectidClass).replace('.', '/');
64         boolean alreadyPNG = false;
65         String JavaDoc sncn = UserId.class.getName().replace('.','/');
66         if (interfaces == null || interfaces.length==0) {
67             itfs = new String JavaDoc[]{pngcn, sncn};
68         } else {
69             int i=0;
70             while(i<interfaces.length && !interfaces[i].equals(pngcn)) {
71                 i++;
72             }
73             alreadyPNG = i<interfaces.length;
74             if (alreadyPNG) {
75                 itfs = interfaces;
76             } else {
77                 itfs = new String JavaDoc[interfaces.length + 2];
78                 System.arraycopy(interfaces, 0, itfs, 2, interfaces.length);
79                 itfs[0] = pngcn;
80                 itfs[1] = UserId.class.getName().replace('.','/');
81             }
82         }
83         if (alreadyPNG) {
84             logger.log(BasicLevel.DEBUG, "The class " + className
85                     + " already contains the interface " + pngcn + " and " + sncn);
86             super.visit(version, access, className, superName, interfaces, sourceFile);
87             return;
88         }
89         logger.log(BasicLevel.DEBUG, "Add to the class " + className
90                 + " the interface " + pngcn);
91         logger.log(BasicLevel.DEBUG, "Add to the class " + className
92                 + " the interface " + sncn);
93         super.visit(version, access, className, superName, itfs, sourceFile);
94
95         SpeedoClass pkFieldClassHolder = jdoClass;
96         if (jdoClass.superClassName != null) {
97             pkFieldClassHolder = jdoClass.getAncestor();
98         }
99
100         for(Iterator JavaDoc it = pkFieldClassHolder.jdoField.values().iterator(); it.hasNext();) {
101             SpeedoField sp = (SpeedoField) it.next();
102             if (sp.primaryKey) {
103                 String JavaDoc methodName = "pnGet" + upperFL(sp.name);
104                 logger.log(BasicLevel.DEBUG, "Add to the class " + className
105                         + " the method " + methodName);
106                 CodeVisitor _cv = this.cv.visitMethod(
107                         Constants.ACC_PUBLIC,
108                         methodName,
109                         "(Ljava/lang/Object;)" + sp.desc,
110                         null,
111                         null);
112                 _cv.visitVarInsn(Constants.ALOAD, 0);
113                 _cv.visitFieldInsn(Constants.GETFIELD, className, sp.name, sp.desc);
114                 Type returnType = Type.getType(sp.desc);
115                 _cv.visitInsn(returnType.getOpcode(Constants.IRETURN));
116                 _cv.visitMaxs(
117                         (sp.desc.equals("J") || sp.desc.equals("D")) ? 2 : 1,
118                         2);
119             }
120         }
121         // declare the field jdoPersistentClassName
122
//int access, String name, String desc, Object value
123
logger.log(BasicLevel.DEBUG, "Add to the class " + className
124                 + " the field " + ADDED_FIELD_NAME);
125         cv.visitField(Constants.ACC_PRIVATE, ADDED_FIELD_NAME,
126                 ADDED_FIELD_DESC, null, null);
127
128         //Add the method jdoGetPersistentClassName
129
String JavaDoc methodName = "jdoGetPersistentClassName";
130         logger.log(BasicLevel.DEBUG, "Add to the class " + className
131                 + " the method " + methodName);
132         CodeVisitor _cv = this.cv.visitMethod(
133                 Constants.ACC_PUBLIC,
134                 methodName,
135                 "()Ljava/lang/String;",
136                 null,
137                 null);
138         _cv.visitVarInsn(Constants.ALOAD, 0);
139         _cv.visitFieldInsn(Constants.GETFIELD,
140                 className, ADDED_FIELD_NAME, ADDED_FIELD_DESC);
141         Type returnType = Type.getType(ADDED_FIELD_DESC);
142         _cv.visitInsn(returnType.getOpcode(Constants.IRETURN));
143         _cv.visitMaxs(1, 2);
144
145         //Add the method jdoSetPersistentClassName
146
methodName = "jdoSetPersistentClassName";
147         logger.log(BasicLevel.DEBUG, "Add to the class " + className
148                 + " the method " + methodName);
149         _cv = this.cv.visitMethod(
150                 Constants.ACC_PUBLIC,
151                 methodName,
152                 "(Ljava/lang/String;)V",
153                 null,
154                 null);
155         _cv.visitVarInsn(Constants.ALOAD, 0);
156         _cv.visitVarInsn(Constants.ALOAD, 1);
157         _cv.visitFieldInsn(Constants.PUTFIELD,
158                 className, ADDED_FIELD_NAME, ADDED_FIELD_DESC);
159         _cv.visitInsn(Constants.RETURN);
160         _cv.visitMaxs(2, 2);
161     }
162
163     public CodeVisitor visitMethod(final int access,
164                                    final String JavaDoc name,
165                                    final String JavaDoc desc,
166                                    final String JavaDoc[] exceptions,
167                                    final Attribute attrs) {
168         CodeVisitor c = cv.visitMethod(access, name, desc, exceptions, attrs);
169         if (name.equals("<init>")) {
170             c.visitVarInsn(Constants.ALOAD, 0);
171             c.visitLdcInsn(jdoClass.getFQName()); //load a constant
172
c.visitFieldInsn(Constants.PUTFIELD, className,
173                 ADDED_FIELD_NAME, ADDED_FIELD_DESC);
174         }
175         return c;
176     }
177
178     private String JavaDoc upperFL(String JavaDoc str) {
179         if (str == null || str.length()==0) {
180             return str;
181         } else if (str.length() == 1) {
182             return String.valueOf(Character.toUpperCase(str.charAt(0)));
183         } else {
184             return Character.toUpperCase(str.charAt(0)) + str.substring(1);
185         }
186     }
187 }
188
Popular Tags