{
// Skip synthetic method
return;
}
MethodGen methodGen = new MethodGen(m, className, constantPoolGen);
InstructionList il = methodGen.getInstructionList();
if ((il == null) || (il.size() == 0))
{
return;
}
InstructionFactory factory = new InstructionFactory(newClass);
boolean isCloneMethod = ("clone".equals(m.getName()) && ((m.getArgumentTypes() == null) || (m.getArgumentTypes().length == 0)));
boolean change = false;
InstructionHandle ih = il.getStart();
while (ih != null)
{
Instruction i = ih.getInstruction();
if ((i instanceof GETFIELD) || (i instanceof PUTFIELD))
{
Field f;
FieldInstruction field = (FieldInstruction) i;
Constant c = m.getConstantPool().getConstant(field.getIndex());
ConstantFieldref fieldRef = (ConstantFieldref) c;
ConstantClass cclass = (ConstantClass) m.getConstantPool().getConstant(fieldRef.getClassIndex());
ConstantUtf8 utfClassName = (ConstantUtf8) m.getConstantPool().getConstant(cclass.getNameIndex());
String utfClassNameString = StringUtils.replaceAll(utfClassName.getBytes().toString(), "/", ".");
JavaClass fieldJavaClass = null;
try
{
fieldJavaClass = Repository.lookupClass(utfClassNameString);
}
catch (Throwable ex)
{
// catch Throwable, so it is compatible with latest BCEL changes in methods signature.
// It nows raises ClassNotFoundException. In order to be able to compible this code
// with bcel-5.1 or bcel-5.1+, we catch as throwable
JPOXLogger.ENHANCER.error(LOCALISER.msg("Enhancer.ClassNotFound", utfClassNameString, ex));
throw new JDOFatalException(LOCALISER.msg("Enhancer.ClassNotFound", utfClassNameString, ex));
}
if (fieldJavaClass == null)
{
throw new JDOFatalException(LOCALISER.msg("Enhancer.ClassNotFound", utfClassNameString,
new NullPointerException()));
}
f = BCELUtils.getFieldByName(field.getName(constantPoolGen), fieldJavaClass);
if (f == null)
{
String message = LOCALISER.msg("Enhancer.FieldIsNull", className, m.getName(), field.getName(constantPoolGen));
JPOXLogger.ENHANCER.error(message);
throw new NullPointerException(message);
}
ClassGen cg = BCELUtils.getClassByFieldByName(field.getName(constantPoolGen), fieldJavaClass);
BCELFieldPropertyMetaData fieldConfig = null;
BCELClassMetaData jdoConfigClass = ((BCELClassMetaData) cmd);
// the accessing class is not this
if (!cg.getClassName().equals(newClass.getClassName()))
{
jdoConfigClass = (BCELClassMetaData) cmd.getPackageMetaData().getFileMetaData().getMetaDataManager().getMetaDataForClass(
cg.getClassName(), clr);
}
if( jdoConfigClass != null )
{
AbstractMemberMetaData apmd = jdoConfigClass.findField(f);
if (apmd == null)
{
//check if a property(getter,setter) exists with this field name
if( jdoConfigClass.findProperty(f)==null )
{
//no fields netiher properties in the class, so something is wrong
String message = LOCALISER.msg("Enhancer.FieldConfigIsNullError", className + "." + f.getName());
JPOXLogger.ENHANCER.fatal(message);
throw new RuntimeException(message);
}
}
if( apmd != null && apmd.getPersistenceModifier() != FieldPersistenceModifier.NONE )
{
// do nothing
}
if (!isFieldAccessInPersistenceCapableClass(ih, m.getConstantPool()))
{
// do nothing
}
else if (fieldConfig != null && fieldConfig.getJdoFieldFlag() == 0)
{
// do nothing
}
else if (f.isStatic() || f.isFinal())
{
// do nothing
}
else if (BCELUtils.isSynthetic(f))
{
// do nothing
}
else
{
if (isDebugEnabled)
{
JPOXLogger.ENHANCER.debug(LOCALISER.msg("Enhancer.EnhanceOriginalMethod",
className + "." + m.getName(), f.getName()));
}
if( apmd != null && !apmd.isProperty() && apmd.getPersistenceModifier() != FieldPersistenceModifier.NONE)
{
//properties do not use jdoXXX methods
if (i instanceof GETFIELD)
{
ih.setInstruction(factory.createInvoke(cg.getClassName(), "jdo" + BCELUtils.getGetterName(f),
field.getType(constantPoolGen), new Type[]{new ObjectType(cg.getClassName())}, Constants.INVOKESTATIC));
}
else
{
ih.setInstruction(factory.createInvoke(cg.getClassName(), "jdo" + BCELUtils.getSetterName(f),
Type.VOID, new Type[]{new ObjectType(cg.getClassName()), field.getType(constantPoolGen)},
Constants.INVOKESTATIC));
}
change = true;
}
}
}
}
else if (isCloneMethod && (i instanceof INVOKESPECIAL))
{
// If this is the clone method and is the root persistence capable, call jdoSuperClone
INVOKESPECIAL is = (INVOKESPECIAL) i;
if ((cmd.getPersistenceCapableSuperclass() == null) && ("clone".equals(is.getMethodName(constantPoolGen))) &&
("()Ljava/lang/Object;".equals(is.getSignature(constantPoolGen))))
{
ih.setInstruction(factory.createInvoke(className, ClassEnhancer.MN_JdoSuperClone, Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
if (isDebugEnabled)
{
JPOXLogger.ENHANCER.debug(LOCALISER.msg("Enhancer.EnhanceOriginalMethod", className + "." + m.getName(), "super.clone()"));
}
change = true;
}
}
ih = ih.getNext();
}
if (change)
{
methodGen.setMaxLocals();
methodGen.setMaxStack();
newClass.replaceMethod(m, methodGen.getMethod());
}
}