Skip to content

Commit

Permalink
#27 - Create AnnotationUsage for filter in XML
Browse files Browse the repository at this point in the history
  • Loading branch information
mbladel committed Oct 24, 2023
1 parent b63b9ca commit 84fe0ce
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.hibernate.models.internal.CollectionHelper.isEmpty;
import static org.hibernate.models.orm.HibernateAnnotations.COLLECTION_TYPE_REG;
import static org.hibernate.models.orm.HibernateAnnotations.COMPOSITE_TYPE_REG;
import static org.hibernate.models.orm.HibernateAnnotations.CONVERTER_REG;
Expand Down Expand Up @@ -418,6 +419,10 @@ public void collectFilterDefinitions(AnnotationTarget annotationTarget) {

private Map<String, ClassDetails> extractFilterParameters(AnnotationUsage<FilterDef> source) {
final List<AnnotationUsage<ParamDef>> parameters = source.getAttributeValue( "parameters" );
if ( isEmpty( parameters ) ) {
return null;
}

final Map<String, ClassDetails> result = new HashMap<>( parameters.size() );
for ( AnnotationUsage<ParamDef> parameter : parameters ) {
result.put( parameter.getAttributeValue( "name" ), parameter.getAttributeValue( "type" ) );
Expand All @@ -438,14 +443,14 @@ public void collectFilterDefinitions(List<JaxbFilterDefImpl> filterDefinitions)
}

private Map<String, ClassDetails> extractFilterParameters(JaxbFilterDefImpl source) {
final List<JaxbFilterDefImpl.JaxbFilterParamImpl> parameters = source.getFilterParam();

// todo : update the mapping.xsd to account for new @ParamDef definition
// todo : handle simplified type names for XML, e.g. "String" instead of "java.lang.String"
final List<JaxbFilterDefImpl.JaxbFilterParamImpl> parameters = source.getFilterParams();
if ( isEmpty( parameters ) ) {
return null;
}

final Map<String, ClassDetails> result = new HashMap<>( parameters.size() );
for ( JaxbFilterDefImpl.JaxbFilterParamImpl parameter : parameters ) {
// for now, don't check whether nothing was specified; this situation this
// for now, don't check whether nothing was specified; this situation
// should resolve to Object - let's see how that reacts
final ClassDetails targetClassDetails = XmlAnnotationHelper.resolveJavaType(
parameter.getType(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,12 @@ public static MutableMemberDetails processElementCollectionAttribute(
XmlAnnotationHelper.applyConvert( jaxbConvert, memberDetails, sourceModelBuildingContext );
} );

// todo : filter
jaxbElementCollection.getFilters().forEach( (jaxbFilter) -> XmlAnnotationHelper.applyFilter(
jaxbFilter,
memberDetails,
sourceModelBuildingContext
) );

// todo : attribute-override
// todo : association-override

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,12 @@ private static void processEntityMetadata(
sourceModelBuildingContext
);

jaxbEntity.getFilters().forEach( jaxbFilter -> XmlAnnotationHelper.applyFilter(
jaxbFilter,
classDetails,
sourceModelBuildingContext
) );

// todo : id-class
// todo : callbacks
// todo : entity-listeners
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import java.util.UUID;

import org.hibernate.annotations.AttributeAccessor;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterJoinTable;
import org.hibernate.annotations.CollectionType;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.JavaType;
Expand All @@ -25,6 +27,7 @@
import org.hibernate.annotations.NaturalIdCache;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.SqlFragmentAlias;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.UuidGenerator;
import org.hibernate.boot.internal.Target;
Expand All @@ -40,6 +43,7 @@
import org.hibernate.boot.jaxb.mapping.spi.JaxbEmbeddedIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntity;
import org.hibernate.boot.jaxb.mapping.spi.JaxbGeneratedValueImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbHbmFilterImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbLobImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbNationalizedImpl;
Expand Down Expand Up @@ -90,6 +94,7 @@
import static java.util.Collections.emptyList;
import static org.hibernate.internal.util.NullnessHelper.coalesce;
import static org.hibernate.models.orm.xml.internal.XmlProcessingHelper.getOrMakeAnnotation;
import static org.hibernate.models.orm.xml.internal.XmlProcessingHelper.getOrMakeNamedAnnotation;
import static org.hibernate.models.orm.xml.internal.XmlProcessingHelper.makeAnnotation;

/**
Expand Down Expand Up @@ -386,7 +391,7 @@ public static void applySequenceGenerator(
return;
}

final MutableAnnotationUsage<SequenceGenerator> sequenceAnn = XmlProcessingHelper.getOrMakeNamedAnnotation(
final MutableAnnotationUsage<SequenceGenerator> sequenceAnn = getOrMakeNamedAnnotation(
SequenceGenerator.class,
jaxbGenerator.getName(),
memberDetails
Expand Down Expand Up @@ -787,4 +792,48 @@ public static void applyJdbcTypeCode(
memberDetails.addAnnotationUsage( typeCodeAnn );
typeCodeAnn.setAttributeValue( "value", jdbcTypeCode );
}

static void applyFilter(
JaxbHbmFilterImpl jaxbFilter,
MutableAnnotationTarget target,
SourceModelBuildingContext sourceModelBuildingContext) {
applyFilter( jaxbFilter, target, Filter.class, sourceModelBuildingContext );
}

static void applyJoinTableFilters(
JaxbHbmFilterImpl jaxbFilter,
MutableAnnotationTarget target,
SourceModelBuildingContext sourceModelBuildingContext) {
applyFilter( jaxbFilter, target, FilterJoinTable.class, sourceModelBuildingContext );
}

private static <F extends Annotation> void applyFilter(
JaxbHbmFilterImpl jaxbFilter,
MutableAnnotationTarget target,
Class<F> filterAnnotationClass,
SourceModelBuildingContext sourceModelBuildingContext) {
// Since @Filter and @FilterJoinTable have exactly the same attributes,
// we can use the same method with parametrized annotation class
final MutableAnnotationUsage<F> filterAnn = getOrMakeNamedAnnotation(
filterAnnotationClass,
jaxbFilter.getName(),
target
);

applyAttributeIfSpecified( filterAnn, "condition", jaxbFilter.getCondition() );
applyAttributeIfSpecified( filterAnn, "deduceAliasInjectionPoints", jaxbFilter.isAutoAliasInjection() );

final List<JaxbHbmFilterImpl.JaxbAliasesImpl> aliases = jaxbFilter.getAliases();
if ( !CollectionHelper.isEmpty( aliases ) ) {
final List<MutableAnnotationUsage<SqlFragmentAlias>> sqlFragmentAliases = new ArrayList<>( aliases.size() );
for ( JaxbHbmFilterImpl.JaxbAliasesImpl alias : aliases ) {
final MutableAnnotationUsage<SqlFragmentAlias> aliasAnn = new DynamicAnnotationUsage<>( SqlFragmentAlias.class );
aliasAnn.setAttributeValue( "alias", alias.getAlias() );
aliasAnn.setAttributeValue( "table", alias.getTable() );
aliasAnn.setAttributeValue( "entity", alias.getEntity() );
sqlFragmentAliases.add( aliasAnn );
}
filterAnn.setAttributeValue( "aliases", sqlFragmentAliases );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
*/
package org.hibernate.models.orm.xml.complete;

import java.util.List;

import org.hibernate.annotations.Filter;
import org.hibernate.annotations.SqlFragmentAlias;
import org.hibernate.models.orm.internal.ManagedResourcesImpl;
import org.hibernate.models.orm.spi.AttributeMetadata;
import org.hibernate.models.orm.spi.EntityHierarchy;
Expand Down Expand Up @@ -87,5 +91,17 @@ public boolean shouldIgnoreUnlistedClasses() {
final AnnotationUsage<Column> nameColumnAnn = nameAttribute.getMember().getAnnotationUsage( Column.class );
assertThat( nameColumnAnn ).isNotNull();
assertThat( nameColumnAnn.<String>getAttributeValue( "name" ) ).isEqualTo( "description" );

validateFilterUsage( root.getClassDetails().getAnnotationUsage( Filter.class ) );
}

private void validateFilterUsage(AnnotationUsage<Filter> filter) {
assertThat( filter ).isNotNull();
assertThat( filter.<String>getAttributeValue( "name" ) ).isEqualTo( "name_filter" );
assertThat( filter.<String>getAttributeValue( "condition" ) ).isEqualTo( "{t}.name = :name" );
final List<AnnotationUsage<SqlFragmentAlias>> aliases = filter.getAttributeValue( "aliases" );
assertThat( aliases ).hasSize( 1 );
assertThat( aliases.get( 0 ).<String>getAttributeValue( "alias" ) ).isEqualTo( "t" );
assertThat( aliases.get( 0 ).<String>getAttributeValue( "table" ) ).isEqualTo( "SimpleEntity" );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.1">
<entity class="org.hibernate.models.orm.xml.SimpleEntity" metadata-complete="true" access="FIELD">
<filter name="name_filter" condition="{t}.name = :name">
<aliases alias="t" table="SimpleEntity" />
</filter>

<attributes>
<id name="id">
<column name="pk"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@ public interface JaxbPluralAttribute extends JaxbPersistentAttribute {
JaxbForeignKeyImpl getMapKeyForeignKey();

void setMapKeyForeignKey(JaxbForeignKeyImpl value);

List<JaxbHbmFilterImpl> getFilters();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1882,7 +1882,10 @@
<!-- </xsd:sequence>-->
<!-- </xsd:choice>-->
<xsd:choice>
<xsd:element name="join-table" type="orm:join-table" minOccurs="0"/>
<xsd:sequence>
<xsd:element name="join-table" type="orm:join-table" minOccurs="0"/>
<xsd:element name="filter-join-table" type="orm:hbm-filter" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:sequence>
<xsd:element name="join-column" type="orm:join-column" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="foreign-key" type="orm:foreign-key" minOccurs="0"/>
Expand All @@ -1891,7 +1894,6 @@
<xsd:element name="cascade" type="orm:cascade-type" minOccurs="0"/>
<xsd:element name="on-delete" type="orm:on-delete-type" minOccurs="0"/>
<xsd:element name="filter" type="orm:hbm-filter" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="filter-join-table" type="orm:hbm-filter" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="target-entity" type="xsd:string"/>
Expand Down Expand Up @@ -2483,7 +2485,7 @@
<xsd:attribute name="name" use="required" type="xsd:string"/>
</xsd:complexType>

<xsd:complexType name="hbm-filter" mixed="true">
<xsd:complexType name="hbm-filter">
<xsd:annotation>
<xsd:documentation>
Applies a filter defined by hbm-filter-def usage
Expand All @@ -2502,7 +2504,6 @@
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="condition" type="xsd:string" />
</xsd:sequence>

<xsd:attribute name="name" use="required" type="xsd:string"/>
Expand Down Expand Up @@ -2858,6 +2859,7 @@
<xsd:element name="discriminator" type="orm:hbm-any-discriminator"/>
<xsd:element name="key" type="orm:hbm-any-key"/>
<xsd:element name="cascade" type="orm:cascade-type" minOccurs="0"/>
<xsd:element name="filter" type="orm:hbm-filter" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>

<xsd:attribute name="name" use="required" type="xsd:string"/>
Expand Down
23 changes: 23 additions & 0 deletions hibernate-orm/src/main/xjb/mapping-bindings.xjb
Original file line number Diff line number Diff line change
Expand Up @@ -293,26 +293,44 @@
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbFetchableAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbBasicMapping</inheritance:implements>
<bindings node=".//xsd:element[@name='filter']">
<property name="filters"/>
</bindings>
</bindings>

<bindings node="//xsd:complexType[@name='one-to-many']">
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbFetchableAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbAssociationAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbNotFoundCapable</inheritance:implements>
<bindings node=".//xsd:element[@name='filter']">
<property name="filters"/>
</bindings>
<bindings node=".//xsd:element[@name='filter-join-table']">
<property name="joinTableFilters"/>
</bindings>
</bindings>

<bindings node="//xsd:complexType[@name='many-to-many']">
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbFetchableAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbAssociationAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbNotFoundCapable</inheritance:implements>
<bindings node=".//xsd:element[@name='filter']">
<property name="filters"/>
</bindings>
<bindings node=".//xsd:element[@name='filter-join-table']">
<property name="joinTableFilters"/>
</bindings>
</bindings>

<bindings node="//xsd:complexType[@name='hbm-many-to-any']">
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbPluralAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbFetchableAttribute</inheritance:implements>
<inheritance:implements>org.hibernate.boot.jaxb.mapping.spi.JaxbAnyMapping</inheritance:implements>
<bindings node=".//xsd:element[@name='filter']">
<property name="filters"/>
</bindings>
<class name="JaxbPluralAnyMappingImpl"/>
</bindings>

Expand Down Expand Up @@ -439,6 +457,11 @@
</bindings>
</bindings>

<bindings node="//xsd:complexType[@name='filter-def']">
<bindings node=".//xsd:element[@name='filter-param']">
<property name="filterParams"/>
</bindings>
</bindings>


<!--
Expand Down

0 comments on commit 84fe0ce

Please sign in to comment.