implement support for Jakarta Data events

(no events for reactive repos)
This commit is contained in:
Gavin King 2024-12-20 19:45:18 +01:00
parent 48a2d9177c
commit c9b6986f69
6 changed files with 107 additions and 23 deletions

View File

@ -108,6 +108,12 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {
pw.println(); pw.println();
// TODO: move this!
if ( context.addDependentAnnotation() && context.isDataEventPackageAvailable()
&& entity.isImplementation() && !entity.isReactive() ) {
pw.println("\t@Inject private Event<? super LifecycleEvent<?>> event;\n");
}
final List<MetaAttribute> members = entity.getMembers(); final List<MetaAttribute> members = entity.getMembers();
for ( MetaAttribute metaMember : members ) { for ( MetaAttribute metaMember : members ) {
if ( metaMember instanceof InnerClassMetaAttribute innerClass ) { if ( metaMember instanceof InnerClassMetaAttribute innerClass ) {

View File

@ -92,6 +92,7 @@ public final class Context {
private AccessType persistenceUnitDefaultAccessType; private AccessType persistenceUnitDefaultAccessType;
private boolean generateJakartaDataStaticMetamodel; private boolean generateJakartaDataStaticMetamodel;
private boolean quarkusInjection; private boolean quarkusInjection;
private boolean dataEventPackageAvailable;
// keep track of all classes for which model have been generated // keep track of all classes for which model have been generated
private final Set<Metamodel> generatedModelClasses = new HashSet<>(); private final Set<Metamodel> generatedModelClasses = new HashSet<>();
@ -224,6 +225,14 @@ public void setQuarkusInjection(boolean quarkusInjection) {
this.quarkusInjection = quarkusInjection; this.quarkusInjection = quarkusInjection;
} }
public boolean isDataEventPackageAvailable() {
return dataEventPackageAvailable;
}
public void setDataEventPackageAvailable(boolean dataEventPackageAvailable) {
this.dataEventPackageAvailable = dataEventPackageAvailable;
}
public Elements getElementUtils() { public Elements getElementUtils() {
return processingEnvironment.getElementUtils(); return processingEnvironment.getElementUtils();
} }

View File

@ -243,6 +243,9 @@ private boolean handleSettings(ProcessingEnvironment environment) {
final PackageElement quarkusOrmPackage = final PackageElement quarkusOrmPackage =
context.getProcessingEnvironment().getElementUtils() context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "io.quarkus.hibernate.orm" ); .getPackageElement( "io.quarkus.hibernate.orm" );
final PackageElement dataEventPackage =
context.getProcessingEnvironment().getElementUtils()
.getPackageElement( "jakarta.data.event" );
PackageElement quarkusOrmPanachePackage = PackageElement quarkusOrmPanachePackage =
context.getProcessingEnvironment().getElementUtils() context.getProcessingEnvironment().getElementUtils()
@ -265,6 +268,7 @@ && packagePresent(quarkusOrmPanachePackage) ) {
context.setAddGeneratedAnnotation( packagePresent(jakartaAnnotationPackage) ); context.setAddGeneratedAnnotation( packagePresent(jakartaAnnotationPackage) );
context.setAddDependentAnnotation( packagePresent(jakartaContextPackage) ); context.setAddDependentAnnotation( packagePresent(jakartaContextPackage) );
context.setAddTransactionScopedAnnotation( packagePresent(jakartaTransactionsPackage) ); context.setAddTransactionScopedAnnotation( packagePresent(jakartaTransactionsPackage) );
context.setDataEventPackageAvailable( packagePresent(dataEventPackage) );
context.setQuarkusInjection( packagePresent(quarkusOrmPackage) ); context.setQuarkusInjection( packagePresent(quarkusOrmPackage) );
context.setUsesQuarkusOrm( packagePresent(quarkusOrmPanachePackage) ); context.setUsesQuarkusOrm( packagePresent(quarkusOrmPanachePackage) );
context.setUsesQuarkusReactive( packagePresent(quarkusReactivePanachePackage) ); context.setUsesQuarkusReactive( packagePresent(quarkusReactivePanachePackage) );

View File

@ -685,6 +685,11 @@ boolean needsDefaultConstructor() {
return null; return null;
} }
@Override
public boolean isReactive() {
return usingReactiveSession(sessionType);
}
private boolean isPanacheType(TypeElement type) { private boolean isPanacheType(TypeElement type) {
return context.usesQuarkusOrm() && isOrmPanacheType( type ) return context.usesQuarkusOrm() && isOrmPanacheType( type )
|| context.usesQuarkusReactive() && isReactivePanacheType( type ); || context.usesQuarkusReactive() && isReactivePanacheType( type );

View File

@ -7,6 +7,9 @@
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import java.util.Set;
import static java.lang.Character.toUpperCase;
import static org.hibernate.processor.util.Constants.LIST; import static org.hibernate.processor.util.Constants.LIST;
import static org.hibernate.processor.util.Constants.UNI; import static org.hibernate.processor.util.Constants.UNI;
@ -60,21 +63,24 @@ public boolean hasStringAttribute() {
return false; return false;
} }
private String capitalize(String string) {
return toUpperCase(string.charAt(0)) + string.substring(1);
}
static final Set<String> eventTypes = Set.of("insert", "update", "delete");
@Override @Override
public String getAttributeDeclarationString() { public String getAttributeDeclarationString() {
StringBuilder declaration = new StringBuilder(); StringBuilder declaration = new StringBuilder();
preamble(declaration); preamble(declaration);
nullCheck(declaration, parameterName); nullCheck(declaration, parameterName);
preEvent(declaration);
if ( !isReactive() ) { if ( !isReactive() ) {
declaration.append( "\ttry {\n" ); declaration.append( "\ttry {\n" );
} }
delegateCall(declaration); delegateCall(declaration);
returnArgument(declaration); returnArgumentReactively(declaration);
if ( !isReactive() ) { if ( !isReactive() ) {
if ( returnArgument ) {
declaration
.append( ";\n" );
}
declaration.append( "\t}\n" ); declaration.append( "\t}\n" );
} }
convertExceptions( declaration ); convertExceptions( declaration );
@ -82,10 +88,77 @@ public String getAttributeDeclarationString() {
declaration declaration
.append( ";\n" ); .append( ";\n" );
} }
postEvent(declaration);
returnArgument(declaration);
declaration.append("}"); declaration.append("}");
return declaration.toString(); return declaration.toString();
} }
private void postEvent(StringBuilder declaration) {
if ( annotationMetaEntity.getContext().isDataEventPackageAvailable()
&& annotationMetaEntity.getContext().addDependentAnnotation()
&& eventTypes.contains( operationName )
&& !isReactive() ) {
final String postEventType = "Post" + capitalize( operationName ) + "Event";
annotationMetaEntity.importType( "jakarta.data.event." + postEventType );
declaration
.append( "\tevent.select(new TypeLiteral<" )
.append( postEventType )
.append( "<" )
.append( annotationMetaEntity.importType( entity ) )
.append( ">>(){})\n\t\t\t.fire(new " )
.append( postEventType )
.append( "<>(" )
.append( parameterName )
.append( "));\n" );
}
}
private void preEvent(StringBuilder declaration) {
if ( annotationMetaEntity.getContext().isDataEventPackageAvailable()
&& annotationMetaEntity.getContext().addDependentAnnotation()
&& eventTypes.contains( operationName )
&& !isReactive()) {
final String preEventType = "Pre" + capitalize( operationName ) + "Event";
annotationMetaEntity.importType( "jakarta.data.event." + preEventType );
annotationMetaEntity.importType( "jakarta.data.event.LifecycleEvent" );
annotationMetaEntity.importType( "jakarta.enterprise.util.TypeLiteral" );
annotationMetaEntity.importType( "jakarta.enterprise.event.Event" );
annotationMetaEntity.importType( "jakarta.inject.Inject" );
declaration
.append( "\tevent.select(new TypeLiteral<" )
.append( preEventType )
.append( "<" )
.append( annotationMetaEntity.importType( entity ) )
.append( ">>(){})\n\t\t\t.fire(new " )
.append( preEventType )
.append( "<>(" )
.append( parameterName )
.append( "));\n" );
}
}
private void returnArgument(StringBuilder declaration) {
if ( returnArgument && !isReactive() ) {
declaration
.append( "\treturn " )
.append( parameterName )
.append( ";\n" );
}
}
private void returnArgumentReactively(StringBuilder declaration) {
if ( isReactive() ) {
if ( returnArgument ) {
declaration
.append( "\n\t\t\t.replaceWith(")
.append(parameterName)
.append(")");
}
}
}
private void convertExceptions(StringBuilder declaration) { private void convertExceptions(StringBuilder declaration) {
if ( operationName.equals("insert") ) { if ( operationName.equals("insert") ) {
handle( declaration, handle( declaration,
@ -102,23 +175,6 @@ private void convertExceptions(StringBuilder declaration) {
"jakarta.data.exceptions.DataException"); "jakarta.data.exceptions.DataException");
} }
private void returnArgument(StringBuilder declaration) {
if ( returnArgument ) {
if ( isReactive() ) {
declaration
.append( "\n\t\t\t" )
.append(".replaceWith(")
.append(parameterName)
.append(")");
}
else {
declaration
.append("\t\treturn ")
.append(parameterName);
}
}
}
private void delegateCall(StringBuilder declaration) { private void delegateCall(StringBuilder declaration) {
if ( isReactive() ) { if ( isReactive() ) {
// TODO: handle the case of an iterable parameter // TODO: handle the case of an iterable parameter
@ -179,7 +235,7 @@ private void argument(StringBuilder declaration) {
if ( isReactive() ) { if ( isReactive() ) {
declaration declaration
.append("All") .append("All")
.append("(") .append("((Object[]) ")
.append(parameterName) .append(parameterName)
.append(")"); .append(")");
} }

View File

@ -60,4 +60,8 @@ public interface Metamodel extends ImportContext {
List<AnnotationMirror> inheritedAnnotations(); List<AnnotationMirror> inheritedAnnotations();
String javadoc(); String javadoc();
default boolean isReactive() {
return false;
}
} }