Skip to content

Commit

Permalink
Create AnnotationUsage for filter-def in XML
Browse files Browse the repository at this point in the history
  • Loading branch information
mbladel authored and sebersole committed Oct 20, 2023
1 parent 25dce1e commit 4bd4363
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.models.orm.internal;

import java.util.Map;

import org.hibernate.models.source.spi.ClassDetails;

/**
* Global registration of a filter definition
*
* @author Marco Belladelli
*/
public class FilterDefRegistration {
private final String name;

private final String defaultCondition;

private final Map<String, ClassDetails> parameters;

public FilterDefRegistration(String name, String defaultCondition, Map<String, ClassDetails> parameters) {
this.name = name;
this.defaultCondition = defaultCondition;
this.parameters = parameters;
}

public String getName() {
return name;
}

public String getDefaultCondition() {
return defaultCondition;
}

public Map<String, ClassDetails> getParameters() {
return parameters;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
import java.util.List;
import java.util.Map;

import org.hibernate.AnnotationException;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.ParamDef;
import org.hibernate.annotations.Parameter;
import org.hibernate.boot.jaxb.mapping.JaxbCollectionUserTypeRegistration;
import org.hibernate.boot.jaxb.mapping.JaxbCompositeUserTypeRegistration;
Expand All @@ -22,6 +25,7 @@
import org.hibernate.boot.jaxb.mapping.JaxbEmbeddableInstantiatorRegistration;
import org.hibernate.boot.jaxb.mapping.JaxbEntityListener;
import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings;
import org.hibernate.boot.jaxb.mapping.JaxbFilterDef;
import org.hibernate.boot.jaxb.mapping.JaxbGenericIdGenerator;
import org.hibernate.boot.jaxb.mapping.JaxbJavaTypeRegistration;
import org.hibernate.boot.jaxb.mapping.JaxbJdbcTypeRegistration;
Expand All @@ -43,10 +47,12 @@
import jakarta.persistence.TableGenerator;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static org.hibernate.models.orm.spi.HibernateAnnotations.COLLECTION_TYPE_REG;
import static org.hibernate.models.orm.spi.HibernateAnnotations.COMPOSITE_TYPE_REG;
import static org.hibernate.models.orm.spi.HibernateAnnotations.CONVERTER_REG;
import static org.hibernate.models.orm.spi.HibernateAnnotations.EMBEDDABLE_INSTANTIATOR_REG;
import static org.hibernate.models.orm.spi.HibernateAnnotations.FILTER_DEF;
import static org.hibernate.models.orm.spi.HibernateAnnotations.JAVA_TYPE_REG;
import static org.hibernate.models.orm.spi.HibernateAnnotations.JDBC_TYPE_REG;
import static org.hibernate.models.orm.spi.HibernateAnnotations.TYPE_REG;
Expand All @@ -67,6 +73,7 @@ public class GlobalRegistrations {
private List<CompositeUserTypeRegistration> compositeUserTypeRegistrations;
private List<CollectionTypeRegistration> collectionTypeRegistrations;
private List<EmbeddableInstantiatorRegistration> embeddableInstantiatorRegistrations;
private Map<String,FilterDefRegistration> filterDefRegistrations;

private Map<String,SequenceGeneratorRegistration> sequenceGeneratorRegistrations;
private Map<String,TableGeneratorRegistration> tableGeneratorRegistrations;
Expand Down Expand Up @@ -121,6 +128,9 @@ public List<EmbeddableInstantiatorRegistration> getEmbeddableInstantiatorRegistr
return embeddableInstantiatorRegistrations == null ? emptyList() : embeddableInstantiatorRegistrations;
}

public Map<String, FilterDefRegistration> getFilterDefRegistrations() {
return filterDefRegistrations == null ? emptyMap() : filterDefRegistrations;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JavaTypeRegistration
Expand Down Expand Up @@ -365,6 +375,62 @@ public void collectEmbeddableInstantiatorRegistration(ClassDetails embeddableCla
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Filter-defs

public void collectFilterDefinitions(AnnotationTarget annotationTarget) {
annotationTarget.forEachAnnotationUsage( FILTER_DEF, (usage) -> collectFilterDefinition(
usage.getAttributeValue( "name" ),
usage.getAttributeValue( "defaultCondition" ),
extractFilterParameters( usage )
) );
}

private Map<String, ClassDetails> extractFilterParameters(AnnotationUsage<FilterDef> source) {
final List<AnnotationUsage<ParamDef>> parameters = source.getAttributeValue( "parameters" );
final Map<String, ClassDetails> result = new HashMap<>( parameters.size() );
for ( AnnotationUsage<ParamDef> parameter : parameters ) {
result.put( parameter.getAttributeValue( "name" ), parameter.getAttributeValue( "type" ) );
}
return result;
}

public void collectFilterDefinitions(List<JaxbFilterDef> filterDefinitions) {
if ( CollectionHelper.isEmpty( filterDefinitions ) ) {
return;
}

filterDefinitions.forEach( (filterDefinition) -> collectFilterDefinition(
filterDefinition.getName(),
filterDefinition.getCondition(),
extractFilterParameters( filterDefinition )
) );
}

private Map<String, ClassDetails> extractFilterParameters(JaxbFilterDef source) {
final List<JaxbFilterDef.JaxbFilterParam> 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 Map<String, ClassDetails> result = new HashMap<>( parameters.size() );
for ( JaxbFilterDef.JaxbFilterParam parameter : parameters ) {
result.put( parameter.getName(), classDetailsRegistry.resolveClassDetails( parameter.getType() ) );
}
return result;
}

public void collectFilterDefinition(String name, String defaultCondition, Map<String, ClassDetails> parameters) {
if ( filterDefRegistrations == null ) {
filterDefRegistrations = new HashMap<>();
}

if ( filterDefRegistrations.put( name, new FilterDefRegistration( name, defaultCondition, parameters ) ) != null ) {
throw new AnnotationException( "Multiple '@FilterDef' annotations define a filter named '" + name + "'" );
}
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// EntityListenerRegistration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void apply(JaxbEntityMappings jaxbRoot) {
getGlobalRegistrations().collectCompositeUserTypeRegistrations( jaxbRoot.getCompositeUserTypeRegistrations() );
getGlobalRegistrations().collectCollectionTypeRegistrations( jaxbRoot.getCollectionUserTypeRegistrations() );
getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( jaxbRoot.getEmbeddableInstantiatorRegistrations() );
getGlobalRegistrations().collectFilterDefinitions( jaxbRoot.getFilterDefinitions() );

final JaxbPersistenceUnitMetadata persistenceUnitMetadata = jaxbRoot.getPersistenceUnitMetadata();
if ( persistenceUnitMetadata != null ) {
Expand All @@ -74,6 +75,7 @@ public void apply(ClassDetails classDetails) {
getGlobalRegistrations().collectCompositeUserTypeRegistrations( classDetails );
getGlobalRegistrations().collectCollectionTypeRegistrations( classDetails );
getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( classDetails );
getGlobalRegistrations().collectFilterDefinitions( classDetails );

if ( areIdGeneratorsGlobal ) {
getGlobalRegistrations().collectIdGenerators( classDetails );
Expand All @@ -91,6 +93,7 @@ public void apply(PackageDetails packageDetails) {
getGlobalRegistrations().collectCompositeUserTypeRegistrations( packageDetails );
getGlobalRegistrations().collectCollectionTypeRegistrations( packageDetails );
getGlobalRegistrations().collectEmbeddableInstantiatorRegistrations( packageDetails );
getGlobalRegistrations().collectFilterDefinitions( packageDetails );

// todo : others?
}
Expand All @@ -115,6 +118,7 @@ public ProcessResult createResult(Set<EntityHierarchy> entityHierarchies) {
getGlobalRegistrations().getCompositeUserTypeRegistrations(),
getGlobalRegistrations().getCollectionTypeRegistrations(),
getGlobalRegistrations().getEmbeddableInstantiatorRegistrations(),
getGlobalRegistrations().getFilterDefRegistrations(),
// jpaNamedQueries == null ? emptyMap() : jpaNamedQueries,
// hibernateNamedHqlQueries == null ? emptyMap() : hibernateNamedHqlQueries,
// hibernateNamedNativeQueries == null ? emptyMap() : hibernateNamedNativeQueries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class ProcessResultImpl implements ProcessResult {
private final List<CompositeUserTypeRegistration> compositeUserTypeRegistrations;
private final List<CollectionTypeRegistration> collectionTypeRegistrations;
private final List<EmbeddableInstantiatorRegistration> embeddableInstantiatorRegistrations;
private final Map<String, FilterDefRegistration> filterDefRegistrations;
private final Map<String, NamedQueryRegistration> jpaNamedQueries;
private final Map<String, NamedQueryRegistration> hibernateNamedHqlQueries;
private final Map<String, NamedQueryRegistration> hibernateNamedNativeQueries;
Expand All @@ -42,6 +43,7 @@ public ProcessResultImpl(
List<CompositeUserTypeRegistration> compositeUserTypeRegistrations,
List<CollectionTypeRegistration> collectionTypeRegistrations,
List<EmbeddableInstantiatorRegistration> embeddableInstantiatorRegistrations,
Map<String, FilterDefRegistration> filterDefRegistrations,
Map<String, NamedQueryRegistration> jpaNamedQueries,
Map<String, NamedQueryRegistration> hibernateNamedHqlQueries,
Map<String, NamedQueryRegistration> hibernateNamedNativeQueries) {
Expand All @@ -54,6 +56,7 @@ public ProcessResultImpl(
this.compositeUserTypeRegistrations = compositeUserTypeRegistrations;
this.collectionTypeRegistrations = collectionTypeRegistrations;
this.embeddableInstantiatorRegistrations = embeddableInstantiatorRegistrations;
this.filterDefRegistrations = filterDefRegistrations;
this.jpaNamedQueries = jpaNamedQueries;
this.hibernateNamedHqlQueries = hibernateNamedHqlQueries;
this.hibernateNamedNativeQueries = hibernateNamedNativeQueries;
Expand Down Expand Up @@ -104,6 +107,11 @@ public List<EmbeddableInstantiatorRegistration> getEmbeddableInstantiatorRegistr
return embeddableInstantiatorRegistrations;
}

@Override
public Map<String, FilterDefRegistration> getFilterDefRegistrations() {
return filterDefRegistrations;
}

@Override
public Map<String, NamedQueryRegistration> getJpaNamedQueries() {
return jpaNamedQueries;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.hibernate.models.orm.internal.CompositeUserTypeRegistration;
import org.hibernate.models.orm.internal.ConversionRegistration;
import org.hibernate.models.orm.internal.EmbeddableInstantiatorRegistration;
import org.hibernate.models.orm.internal.FilterDefRegistration;
import org.hibernate.models.orm.internal.JavaTypeRegistration;
import org.hibernate.models.orm.internal.JdbcTypeRegistration;
import org.hibernate.models.orm.internal.NamedQueryRegistration;
Expand Down Expand Up @@ -44,6 +45,8 @@ public interface ProcessResult {

List<EmbeddableInstantiatorRegistration> getEmbeddableInstantiatorRegistrations();

Map<String, FilterDefRegistration> getFilterDefRegistrations();

Map<String, NamedQueryRegistration> getJpaNamedQueries();

Map<String, NamedQueryRegistration> getHibernateNamedHqlQueries();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import java.util.UUID;

import org.hibernate.annotations.ConverterRegistration;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.JavaTypeRegistration;
import org.hibernate.annotations.ParamDef;
import org.hibernate.id.IncrementGenerator;
import org.hibernate.type.descriptor.java.StringJavaType;

Expand Down Expand Up @@ -38,6 +40,7 @@
@NamedStoredProcedureQuery(name = "jpaCallable", procedureName = "jpa_callable")
@org.hibernate.annotations.NamedQuery(name = "ormHql", query = "from Person")
@org.hibernate.annotations.NamedNativeQuery(name = "ormNative", query = "select * from persons")
@FilterDef(name = "name_filter", defaultCondition = "name = :name", parameters = {@ParamDef(name = "name", type = String.class)})
public class Person {
@Id
private Integer id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
package org.hibernate.models.orm.process;

import java.util.Iterator;
import java.util.Map;

import org.hibernate.models.orm.internal.FilterDefRegistration;
import org.hibernate.models.orm.internal.ManagedResourcesImpl;
import org.hibernate.models.orm.spi.EntityHierarchy;
import org.hibernate.models.orm.spi.EntityTypeMetadata;
Expand All @@ -17,6 +19,7 @@
import org.hibernate.models.orm.spi.Processor;
import org.hibernate.models.source.SourceModelTestHelper;
import org.hibernate.models.source.internal.SourceModelBuildingContextImpl;
import org.hibernate.models.source.spi.ClassDetails;
import org.hibernate.type.CharBooleanConverter;
import org.hibernate.type.YesNoConverter;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
Expand Down Expand Up @@ -111,6 +114,8 @@ public boolean shouldIgnoreUnlistedClasses() {
validatePersonHierarchy( two );
validateJoinedHierarchy( one );
}

validateFilterDefs( processResult.getFilterDefRegistrations() );
}

private void validatePersonHierarchy(EntityHierarchy hierarchy) {
Expand Down Expand Up @@ -145,4 +150,15 @@ private void validateJoinedHierarchy(EntityHierarchy hierarchy) {
assertThat( subMetadata.hasSubTypes() ).isFalse();
assertThat( subMetadata.getNumberOfSubTypes() ).isEqualTo( 0 );
}

private void validateFilterDefs(Map<String, FilterDefRegistration> filterDefRegistrations) {
assertThat( filterDefRegistrations ).hasSize( 1 );
assertThat( filterDefRegistrations ).containsKey( "name_filter" );
final FilterDefRegistration nameFilter = filterDefRegistrations.get( "name_filter" );
assertThat( nameFilter.getDefaultCondition() ).isEqualTo( "name = :name" );
final Map<String, ClassDetails> parameters = nameFilter.getParameters();
assertThat( parameters ).hasSize( 1 );
assertThat( parameters ).containsKey( "name" );
assertThat( parameters.get( "name" ).getName() ).isEqualTo( String.class.getName() );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@
package org.hibernate.models.orm.xml;

import java.util.List;
import java.util.Map;

import org.hibernate.boot.jaxb.mapping.JaxbEntityMappings;
import org.hibernate.models.orm.internal.FilterDefRegistration;
import org.hibernate.models.orm.internal.GlobalRegistrations;
import org.hibernate.models.orm.internal.ProcessResultCollector;
import org.hibernate.models.orm.xml.internal.XmlDocumentImpl;
import org.hibernate.models.orm.xml.spi.XmlResources;
import org.hibernate.models.orm.xml.spi.PersistenceUnitMetadata;
import org.hibernate.models.source.SourceModelTestHelper;
import org.hibernate.models.source.internal.StringTypeDescriptor;
import org.hibernate.models.source.spi.ClassDetails;
import org.hibernate.models.source.spi.SourceModelBuildingContext;
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;

Expand Down Expand Up @@ -134,5 +137,18 @@ void testSimpleGlobalXmlProcessing() {
assertThat( globalRegistrations.getConverterRegistrations() ).hasSize( 1 );
assertThat( globalRegistrations.getConverterRegistrations().get(0).getConverterType().getClassName() )
.isEqualTo( org.hibernate.type.YesNoConverter.class.getName() );

validateFilterDefs( globalRegistrations.getFilterDefRegistrations() );
}

private void validateFilterDefs(Map<String, FilterDefRegistration> filterDefRegistrations) {
assertThat( filterDefRegistrations ).hasSize( 1 );
assertThat( filterDefRegistrations ).containsKey( "amount_filter" );
final FilterDefRegistration filterDef = filterDefRegistrations.get( "amount_filter" );
assertThat( filterDef.getDefaultCondition() ).isEqualTo( "amount = :amount" );
final Map<String, ClassDetails> parameters = filterDef.getParameters();
assertThat( parameters ).hasSize( 1 );
assertThat( parameters ).containsKey( "amount" );
assertThat( parameters.get( "amount" ).getName() ).isEqualTo( Integer.class.getName() );
}
}
5 changes: 5 additions & 0 deletions hibernate-models-orm/src/test/resources/mappings/globals.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@
<user-type class="java.util.UUID" descriptor="org.hibernate.models.orm.xml.MyUserType"/>

<conversion converter="org.hibernate.type.YesNoConverter" class="boolean" auto-apply="true"/>

<filter-def name="amount_filter">
<filter-param name="amount" type="java.lang.Integer"/>
<condition>amount = :amount</condition>
</filter-def>
</entity-mappings>

0 comments on commit 4bd4363

Please sign in to comment.