All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hibernate.bytecode.enhance.internal.bytebuddy.FieldAccessEnhancer Maven / Gradle / Ivy
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.bytecode.enhance.internal.bytebuddy;
import javax.persistence.Id;
import net.bytebuddy.description.method.MethodList;
import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.EnhancerConstants;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.jar.asm.Type;
import net.bytebuddy.pool.TypePool;
import static net.bytebuddy.matcher.ElementMatchers.hasDescriptor;
import static net.bytebuddy.matcher.ElementMatchers.named;
class FieldAccessEnhancer implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper {
private static final CoreMessageLogger log = CoreLogging.messageLogger( FieldAccessEnhancer.class );
private final TypeDescription managedCtClass;
private final ByteBuddyEnhancementContext enhancementContext;
private final TypePool classPool;
FieldAccessEnhancer(TypeDescription managedCtClass, ByteBuddyEnhancementContext enhancementContext, TypePool classPool) {
this.managedCtClass = managedCtClass;
this.enhancementContext = enhancementContext;
this.classPool = classPool;
}
@Override
public MethodVisitor wrap(
TypeDescription instrumentedType,
MethodDescription instrumentedMethod,
MethodVisitor methodVisitor,
Implementation.Context implementationContext,
TypePool typePool,
int writerFlags,
int readerFlags) {
return new MethodVisitor( Opcodes.ASM5, methodVisitor ) {
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if ( opcode != Opcodes.GETFIELD && opcode != Opcodes.PUTFIELD ) {
super.visitFieldInsn( opcode, owner, name, desc );
return;
}
FieldDescription field = findField( owner, name, desc );
if ( ( enhancementContext.isEntityClass( field.getDeclaringType().asErasure() )
|| enhancementContext.isCompositeClass( field.getDeclaringType().asErasure() ) )
&& !field.getType().asErasure().equals( managedCtClass )
&& enhancementContext.isPersistentField( field )
&& !EnhancerImpl.isAnnotationPresent( field, Id.class )
&& !field.getName().equals( "this$0" ) ) {
log.debugf(
"Extended enhancement: Transforming access to field [%s.%s] from method [%s#%s]",
field.getType().asErasure(),
field.getName(),
field.getName(),
name
);
switch ( opcode ) {
case Opcodes.GETFIELD:
methodVisitor.visitMethodInsn(
Opcodes.INVOKEVIRTUAL,
owner,
EnhancerConstants.PERSISTENT_FIELD_READER_PREFIX + name,
Type.getMethodDescriptor( Type.getType( desc ) ),
false
);
return;
case Opcodes.PUTFIELD:
methodVisitor.visitMethodInsn(
Opcodes.INVOKEVIRTUAL,
owner,
EnhancerConstants.PERSISTENT_FIELD_WRITER_PREFIX + name,
Type.getMethodDescriptor( Type.getType( void.class ), Type.getType( desc ) ),
false
);
return;
default:
throw new EnhancementException( "Unexpected opcode: " + opcode );
}
}
else {
super.visitFieldInsn( opcode, owner, name, desc );
}
}
};
}
private FieldDescription findField(String owner, String name, String desc) {
TypePool.Resolution resolution = classPool.describe( owner.replace( '/', '.' ) );
if ( !resolution.isResolved() ) {
final String msg = String.format(
"Unable to perform extended enhancement - Unable to locate [%s]",
owner.replace( '/', '.' )
);
throw new EnhancementException( msg );
}
FieldList fields = resolution.resolve().getDeclaredFields().filter( named( name ).and( hasDescriptor( desc ) ) );
if ( fields.size() != 1 ) {
final String msg = String.format(
"Unable to perform extended enhancement - No unique field [%s] defined by [%s]",
name,
owner.replace( '/', '.' )
);
throw new EnhancementException( msg );
}
return fields.getOnly();
}
}