1 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.ClassReader; 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.metadata.SpeedoModifier; 28 import org.objectweb.speedo.generation.api.SpeedoCompilerParameter; 29 import org.objectweb.util.monolog.api.Logger; 30 import org.objectweb.util.monolog.api.BasicLevel; 31 32 import java.io.ObjectStreamClass ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 import java.util.Collection ; 36 37 42 public class ClassInfoAnalyzer extends LoggedClass implements ClassVisitor { 43 44 48 final EnhancerComponent enhancer; 49 50 53 final SpeedoClass jdoClass; 54 55 58 private final Collection xmlDescriptors; 59 60 67 public ClassInfoAnalyzer(final EnhancerComponent enhancer, 68 final SpeedoClass jdoClass, 69 final Collection xmlDescriptors, 70 Logger logger) { 71 super(logger); 72 this.enhancer = enhancer; 73 this.jdoClass = jdoClass; 74 this.xmlDescriptors = xmlDescriptors; 75 } 76 77 80 public void visit(final int version, final int access, 81 final String name, 82 final String superName, 83 final String [] interfaces, 84 final String sourceFile) { 85 jdoClass.signature = Util.modifier(access & ~Constants.ACC_SUPER); 87 jdoClass.isAbstract = (access & Constants.ACC_ABSTRACT) != 0; 88 89 String superClass = jdoClass.superClassName; 91 if (superClass != null && !superClass.equals("") && 92 !superClass.equals(superName.replace('/', '.'))) { 93 throw new RuntimeException ("Class " + name + " has actually " + 94 superName + " as super class, whereas the .jdo file spcifies '" 95 + jdoClass.superClassName + "'"); 96 } 97 for (int i = 0; i < interfaces.length; i++) { 99 if (interfaces[i].equals("javax/jdo/InstanceCallbacks")) 100 jdoClass.isInstanceCallbacks = true; 101 if (interfaces[i].equals("java/io/Serializable")) 102 jdoClass.isSerializable = true; 103 } 104 105 ClassFieldFinder finder = new ClassFieldFinder(); 108 Iterator i = jdoClass.jdoField.values().iterator(); 109 while (i.hasNext()) { 112 SpeedoField current = (SpeedoField) i.next(); 113 if (!finder.fillInfo(current)) 115 throw new RuntimeException ( 116 "Persistent Field " + current.name + 117 " not defined in class " + name); 118 if (current.persistenceModifier == SpeedoModifier.missing) 119 current.persistenceModifier = 120 (Util.isPersistentType(current.desc, xmlDescriptors)) ? 121 SpeedoModifier.persistent : 122 SpeedoModifier.none; 123 } 124 if (jdoClass.isSerializable) { 126 try { 127 ObjectStreamClass oserial = ObjectStreamClass.lookup( 128 Class.forName(name.replace('/', '.'))); 129 jdoClass.VersionUID = oserial.getSerialVersionUID(); 130 } catch (Exception e) { 131 } 132 } 133 } 134 135 public void visitInnerClass(final String name, 136 final String outerName, 137 final String innerName, 138 final int access) { 139 } 141 142 public void visitField(final int access, 143 final String name, 144 final String desc, 145 final Object value, 146 final Attribute attrs) { 147 if ((access & Constants.ACC_STATIC) == 0 150 && (access & Constants.ACC_FINAL) == 0 151 && (access & Constants.ACC_SYNTHETIC) == 0) { 152 SpeedoField jdoField = (SpeedoField) jdoClass.jdoField.get(name); 153 if (jdoField == null 154 && Util.isAutomaticPersistentType(desc, xmlDescriptors)) { 155 jdoField = new SpeedoField(); 156 jdoField.persistenceModifier = SpeedoModifier.persistent; 157 jdoField.name = name; 158 jdoField.access = access; 159 jdoField.desc = desc; 160 jdoClass.add(jdoField); 161 } 162 } 163 } 164 165 public CodeVisitor visitMethod(final int access, 166 final String name, 167 final String desc, 168 final String [] exceptions, 169 final Attribute attrs) { 170 if ("<init>".equals(name) && "()V".equals(desc)) { 171 jdoClass.noArgConstructorStatus = ((access & Constants.ACC_PUBLIC) == 0 172 ? SpeedoClass.NON_PUBLIC_NO_ARG_CONSTRUCTOR 173 : SpeedoClass.PUBLIC_NO_ARG_CONSTRUCTOR); 174 if (logger.isLoggable(BasicLevel.DEBUG)) { 175 logger.log(BasicLevel.DEBUG, jdoClass.getFQName() 176 + ".noArgConstructorStatus=" + jdoClass.noArgConstructorStatus); 177 } 178 } 179 return null; 180 } 181 182 public void visitAttribute(Attribute attribute) { 183 } 185 186 public void visitEnd() { 187 190 for (Iterator it = jdoClass.jdoField.entrySet().iterator();it.hasNext();) { 191 Map.Entry entry = (Map.Entry ) it.next(); 192 SpeedoField field = (SpeedoField) entry.getValue(); 193 if (field.persistenceModifier != SpeedoModifier.persistent) { 194 it.remove(); 195 } 196 } 197 } 198 199 202 class ClassFieldFinder implements ClassVisitor { 203 204 207 private SpeedoField result; 208 boolean find = false; 209 210 public boolean fillInfo(SpeedoField sf) { 211 this.result = sf; 212 String className = sf.jdoClass.getFQName(); 213 SpeedoCompilerParameter scp = enhancer.getSpeedoCompilerParameter(); 214 try { 215 find = false; 216 while (true) { 217 ClassReader cr = enhancer.loadJavaClass(enhancer.isSrcJar, 219 className, scp.output, false); 220 cr.accept(this, true); 221 if (find) { 222 return true; 223 } 224 225 className = jdoClass.superClassName; 227 if (className == null || className.length() == 0) { 228 return false; 231 } 232 } 233 } catch (Exception e) { 234 e.printStackTrace(); 235 return false; 236 } 237 } 238 239 public void visit(final int version, 240 final int access, 241 final String name, 242 final String superName, 243 final String [] interfaces, 244 final String sourceFile) { 245 } 247 248 public void visitInnerClass(final String name, 249 final String outerName, 250 final String innerName, 251 final int access) { 252 } 254 255 public void visitField(final int access, 256 final String name, 257 final String desc, 258 final Object value, 259 final Attribute attrs) { 260 if (name.equals(result.name)) { 261 result.access = access; 263 result.desc = desc; 264 find = true; 265 } 266 } 267 268 public CodeVisitor visitMethod(final int access, 269 final String name, 270 final String desc, 271 final String [] exceptions, 272 final Attribute attrs) { 273 return null; 275 } 276 277 public void visitAttribute(Attribute attribute) { 278 } 280 281 public void visitEnd() { 282 } 284 } 285 } 286 | Popular Tags |