Skip to content

Commit

Permalink
#53 - Simplified creation and addition of attributes for dynamic models
Browse files Browse the repository at this point in the history
#54 - Simplified creation and addition of AnnotationUsage references
#55 - Clean up unused methods
  • Loading branch information
sebersole committed Mar 27, 2024
1 parent db8506f commit 0c09cf1
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 107 deletions.
52 changes: 17 additions & 35 deletions src/main/java/org/hibernate/models/internal/ModifierUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,22 @@

import org.hibernate.models.spi.MemberDetails;

import static java.lang.reflect.Modifier.ABSTRACT;

/**
* Fills-in non-public aspects of the {@link Modifier} class
*
* @author Steve Ebersole
*/
public class ModifierUtils {

private static final int BRIDGE = 0x00000040;
private static final int SYNTHETIC = 0x00001000;
public static final int BRIDGE = 0x00000040;
public static final int SYNTHETIC = 0x00001000;

public static final int DYNAMIC_ATTRIBUTE_MODIFIERS = ~Modifier.ABSTRACT
& ~BRIDGE
& ~Modifier.FINAL
& ~Modifier.STATIC
& ~SYNTHETIC
& ~Modifier.TRANSIENT;

/**
* Disallow instantiation. This is a utility class, use statically.
Expand Down Expand Up @@ -78,7 +83,7 @@ public static boolean isBridge(int modifierFlags) {
}

public static boolean isAbstract(int modifierFlags) {
return (modifierFlags & ABSTRACT) != 0;
return (modifierFlags & Modifier.ABSTRACT) != 0;
}

/**
Expand All @@ -91,19 +96,9 @@ public static boolean isAbstract(int modifierFlags) {
* @see MemberDetails#isPersistable()
*/
public static boolean hasPersistableFieldModifiers(int modifierFlags) {
if ( isTransient( modifierFlags ) ) {
return false;
}

if ( ModifierUtils.isSynthetic( modifierFlags ) ) {
return false;
}

if ( ModifierUtils.isStatic( modifierFlags ) ) {
return false;
}

return true;
return !isTransient( modifierFlags )
&& !isSynthetic( modifierFlags )
&& !isStatic( modifierFlags );
}

/**
Expand All @@ -116,22 +111,9 @@ public static boolean hasPersistableFieldModifiers(int modifierFlags) {
* @see MemberDetails#isPersistable()
*/
public static boolean hasPersistableMethodModifiers(int modifierFlags) {
if ( ModifierUtils.isStatic( modifierFlags ) ) {
return false;
}

if ( ModifierUtils.isBridge( modifierFlags ) ) {
return false;
}

if ( isTransient( modifierFlags ) ) {
return false;
}

if ( ModifierUtils.isSynthetic( modifierFlags ) ) {
return false;
}

return true;
return !isStatic( modifierFlags )
&& !isBridge( modifierFlags )
&& !isTransient( modifierFlags )
&& !isSynthetic( modifierFlags );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ public void clearAnnotationUsages() {
usageMap.clear();
}

@Override
public <X extends Annotation> void removeAnnotationUsage(Class<X> annotationType) {
usageMap.remove( annotationType );
}

/**
* Applies the given {@code annotationUsage} to this target.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

import org.hibernate.models.internal.ClassDetailsSupport;
import org.hibernate.models.internal.ClassTypeDetailsImpl;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MethodDetails;
Expand All @@ -19,6 +21,7 @@
import org.hibernate.models.spi.TypeDetails;
import org.hibernate.models.spi.TypeVariableDetails;

import static org.hibernate.models.internal.ModifierUtils.DYNAMIC_ATTRIBUTE_MODIFIERS;
import static org.hibernate.models.internal.util.StringHelper.isEmpty;

/**
Expand Down Expand Up @@ -166,6 +169,52 @@ public void addMethod(MethodDetails methodDetails) {
this.methods.add( methodDetails );
}

/**
* Creates a field representing an attribute and adds it to this class.
*/
public DynamicFieldDetails applyAttribute(
String name,
ClassDetails type,
boolean isArray,
boolean isPlural,
Consumer<DynamicFieldDetails> configuration,
SourceModelBuildingContext context) {
return applyAttribute(
name,
new ClassTypeDetailsImpl( type, TypeDetails.Kind.CLASS ),
isArray,
isPlural,
configuration,
context
);
}

/**
* Creates a field representing an attribute and adds it to this class
*/
public DynamicFieldDetails applyAttribute(
String name,
TypeDetails type,
boolean isArray,
boolean isPlural,
Consumer<DynamicFieldDetails> configuration,
SourceModelBuildingContext context) {
final DynamicFieldDetails attribute = new DynamicFieldDetails(
name,
type,
this,
DYNAMIC_ATTRIBUTE_MODIFIERS,
isArray,
isPlural,
context
);
if ( configuration != null ) {
configuration.accept( attribute );
}
addField( attribute );
return attribute;
}

@Override
public <X> Class<X> toJavaClass() {
if ( javaType == null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import java.util.Collection;
import java.util.Map;

import org.hibernate.models.spi.MutableMemberDetails;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.FieldDetails;
import org.hibernate.models.spi.MutableMemberDetails;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.models.spi.TypeDetails;
import org.hibernate.models.spi.TypeVariableScope;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ public void clearAnnotationUsages() {
getUsageMap().clear();
}

@Override
public <X extends Annotation> void removeAnnotationUsage(Class<X> annotationType) {
usageMap.remove( annotationType );
}

@Override
public <X extends Annotation> void addAnnotationUsage(AnnotationUsage<X> annotationUsage) {
getUsageMap().put( annotationUsage.getAnnotationType(), annotationUsage );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,6 @@ public void clearAnnotationUsages() {
getUsageMap().clear();
}

@Override
public <X extends Annotation> void removeAnnotationUsage(Class<X> annotationType) {
if ( usagesMap != null ) {
usagesMap.remove( annotationType );
}
}

@Override
public <X extends Annotation> void addAnnotationUsage(AnnotationUsage<X> annotationUsage) {
getUsageMap().put( annotationUsage.getAnnotationType(), annotationUsage );
Expand Down
32 changes: 21 additions & 11 deletions src/main/java/org/hibernate/models/spi/AnnotationDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,7 @@ default <V> AttributeDescriptor<V> getAttribute(String name) {
* @param context Access to needed services
*/
default MutableAnnotationUsage<A> createUsage(AnnotationTarget target, SourceModelBuildingContext context) {
final DynamicAnnotationUsage<A> usage = new DynamicAnnotationUsage<>( this, target, context );
getAttributes().forEach( (attr) -> {
final Object value = attr.getTypeDescriptor().createValue( attr, target, context );
if ( value != null ) {
usage.setAttributeValue( attr.getName(), value );
}
} );
return usage;
return createUsage( target, null, context );
}

/**
Expand All @@ -113,9 +106,26 @@ default MutableAnnotationUsage<A> createUsage(AnnotationTarget target, SourceMod
* @param adjuster Callback to allow adjusting the created usage prior to return.
* @param context Access to needed services
*/
default MutableAnnotationUsage<A> createUsage(AnnotationTarget target, Consumer<MutableAnnotationUsage<A>> adjuster, SourceModelBuildingContext context) {
final MutableAnnotationUsage<A> usage = createUsage( target, context );
adjuster.accept( usage );
default MutableAnnotationUsage<A> createUsage(
AnnotationTarget target,
Consumer<MutableAnnotationUsage<A>> adjuster,
SourceModelBuildingContext context) {
// create the "empty" usage
final DynamicAnnotationUsage<A> usage = new DynamicAnnotationUsage<>( this, target, context );

// apply attribute defaults
getAttributes().forEach( (attr) -> {
final Object value = attr.getTypeDescriptor().createValue( attr, target, context );
if ( value != null ) {
usage.setAttributeValue( attr.getName(), value );
}
} );

// allow configuration
if ( adjuster != null ) {
adjuster.accept( usage );
}

return usage;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,43 @@
package org.hibernate.models.spi;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.function.Consumer;

/**
* Extension of AnnotationTarget which allows manipulation of the annotations
*
* @author Steve Ebersole
*/
public interface MutableAnnotationTarget extends AnnotationTarget {
/**
* Removes all annotation usages currently associated with this target.
* Useful for complete XML mappings.
*/
void clearAnnotationUsages();

<X extends Annotation> void removeAnnotationUsage(Class<X> annotationType);

/**
* Add an annotation usage to this target
*/
<X extends Annotation> void addAnnotationUsage(AnnotationUsage<X> annotationUsage);

default <X extends Annotation> void addAnnotationUsages(List<AnnotationUsage<X>> annotationUsages) {
annotationUsages.forEach( this::addAnnotationUsage );
/**
* Creates a usage and adds it to this target.
*/
default <A extends Annotation> MutableAnnotationUsage<A> applyAnnotationUsage(
AnnotationDescriptor<A> annotationType,
SourceModelBuildingContext buildingContext) {
return applyAnnotationUsage( annotationType, null, buildingContext );
}

/**
* Creates a usage and adds it to this target, allowing for configuration of the created usage
*/
default <A extends Annotation> MutableAnnotationUsage<A> applyAnnotationUsage(
AnnotationDescriptor<A> annotationType,
Consumer<MutableAnnotationUsage<A>> configuration,
SourceModelBuildingContext buildingContext) {
final MutableAnnotationUsage<A> usage = annotationType.createUsage( this, configuration, buildingContext );
addAnnotationUsage( usage );
return usage;
}
}
Loading

0 comments on commit 0c09cf1

Please sign in to comment.