Skip to content

Commit

Permalink
Cleanup tasks
Browse files Browse the repository at this point in the history
- Difference between Attribute.of/path does not matter -> use 'of'
- Error message when creating Attribute with 'null' name/type, as this happens when it is forgotten that JPA metamodel is not initialized in MockMvc web tests
  • Loading branch information
p3t committed Nov 19, 2024
1 parent 48feb4d commit 17e43a2
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public enum DataRecordAttribute {

ID( Attribute.of( DataRecord_.ID, UUID.class ) ),
NAME( Attribute.of( DataRecord_.NAME, String.class ) ),
CREATED_AT( Attribute.path( DataRecord_.AUDIT_INFO, AuditInfo.class, AuditInfo_.CREATED_AT, Instant.class ) ),
MODIFIED_AT( Attribute.path( DataRecord_.AUDIT_INFO, AuditInfo.class, AuditInfo_.MODIFIED_AT, Instant.class ) );
CREATED_AT( Attribute.of( DataRecord_.AUDIT_INFO, AuditInfo.class, AuditInfo_.CREATED_AT, Instant.class ) ),
MODIFIED_AT( Attribute.of( DataRecord_.AUDIT_INFO, AuditInfo.class, AuditInfo_.MODIFIED_AT, Instant.class ) );

private final Attribute attribute;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void shouldSerializePageRequestsWithOrFilter() {

@Test
void shouldSerializePageRequestsWithMultipleAttributes() {
final var attribute1 = Attribute.path( //
final var attribute1 = Attribute.of( //
SingleAttribute.of( "one", TestEntity.class ), //
SingleAttribute.of( "two", Instant.class ) );
final var attribute2 = Attribute.of( "three", Integer.class );
Expand Down Expand Up @@ -132,7 +132,7 @@ void shouldSerializeTotalCountIfPresent() {

@Test
void shouldDeserializeAndFilter() {
PageRequest<TestEntity> request = PageRequest.create( r -> r.filter(
final PageRequest<TestEntity> request = PageRequest.create( r -> r.filter(
Filters.and( attribute( TestEntity_.id ).equalTo( 123L ),
attribute( TestEntity_.name ).like( "%bumlux%" ) ) ).asc( TestEntity_.id ) );
final RequestSerializer<TestEntity> serializer = RequestSerializer.create();
Expand All @@ -144,7 +144,7 @@ void shouldDeserializeAndFilter() {

@Test
void shouldSerializeParametersOfFilterRules() {
Map<String, List<String>> parameters = Map.of( "Test1", List.of( "Value1" ) );
final Map<String, List<String>> parameters = Map.of( "Test1", List.of( "Value1" ) );
final var request = createPageRequest().copy( b -> b.rule( newTestRule( "TestRule", parameters ) ) );
final RequestSerializer<TestEntity> serializer = RequestSerializer.create(
c -> c.filterRuleFactory( "TestRule", p -> newTestRule( "TestRule", p ) ) );
Expand Down Expand Up @@ -186,7 +186,7 @@ void shouldLearnAttributesBySerializing() {
}

private PageRequest<TestEntity> createPageRequest() {
final var attribute1 = Attribute.path( //
final var attribute1 = Attribute.of( //
SingleAttribute.of( "one", TestEntity.class ), //
SingleAttribute.of( "two", Instant.class ) );
final var attribute2 = Attribute.of( "three", Integer.class );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class Attribute {

private final boolean ignoreCase;

public Attribute( List<SingleAttribute> attributes ) {
public Attribute( final List<SingleAttribute> attributes ) {
this.attributes = attributes;
this.ignoreCase = false;
}
Expand All @@ -56,32 +56,51 @@ public static Attribute of( final SingularAttribute<?, ? extends Comparable<?>>
}

/**
* Creates a new attribute with a path of single attributes. This is needed to address properties of embedded
* entities
* Creates a new attribute as path of single attributes. This is needed to address properties of embedded entities
*
* @param path Path pointing to an attribute (of an embedded entity)
* @return The attribute describing the path and the type of the single attributes
*/
public static Attribute path( final jakarta.persistence.metamodel.Attribute<?, ?>... path ) {
public static Attribute of( final jakarta.persistence.metamodel.Attribute<?, ?>... path ) {
return new Attribute( Arrays.stream( path ).map( SingleAttribute::of ).toList() );
}

/**
* Creates a new attribute with a path of single attributes. This is needed to address properties of embedded
* Creates a new attribute with as path of single attributes. This is needed to address properties of embedded
* entities
*
* @param path Path pointing to an attribute (of an embedded entity)
* @return The attribute describing the path and the type of the single attributes
*/
public static Attribute path( final SingleAttribute... path ) {
public static Attribute of( final SingleAttribute... path ) {
return new Attribute( Arrays.asList( path ) );
}

public static Attribute path( final String name1, final Class<?> type1, final String name2, final Class<?> type2 ) {
/**
* Creates an attribute as path of 2 attributes
*
* @param name1 Attribute name 1
* @param type1 Type of attribute 1
* @param name2 Attribute name 2
* @param type2 Type of attribute 2
* @return The attribute describing the path and type to the specified attribute
*/
public static Attribute of( final String name1, final Class<?> type1, final String name2, final Class<?> type2 ) {
return new Attribute( List.of( SingleAttribute.of( name1, type1 ), SingleAttribute.of( name2, type2 ) ) );
}

public static Attribute path( final String name1, final Class<?> type1, final String name2, final Class<?> type2,
/**
* Creates an attribute as path of 3 attributes
*
* @param name1 Attribute name 1
* @param type1 Type of attribute 1
* @param name2 Attribute name 2
* @param type2 Type of attribute 2
* @param name3 Attribute name 3
* @param type3 Type of attribute 3
* @return The attribute describing the path and type to the specified attribute
*/
public static Attribute of( final String name1, final Class<?> type1, final String name2, final Class<?> type2,
final String name3, final Class<?> type3 ) {
return new Attribute( List.of( SingleAttribute.of( name1, type1 ), SingleAttribute.of( name2, type2 ),
SingleAttribute.of( name3, type3 ) ) );
Expand Down Expand Up @@ -122,7 +141,7 @@ public String name() {
* @param root The root of the entity
* @param <E> Entity type
* @param <V> Value type
* @return The path to the attribute
* @return The path-expression to the attribute
*/
public <E, V extends Comparable<? super V>> Expression<V> path( final Root<E> root ) {
Path<?> path = root;
Expand All @@ -135,14 +154,14 @@ public <E, V extends Comparable<? super V>> Expression<V> path( final Root<E> ro
}

/**
* Get the type of the last attribute in the path
* Get the type of the last attribute in the of
*
* @param <V> Expected Value type
* @return the value type
*/
@SuppressWarnings( "unchecked" )
public <V extends Comparable<? super V>> Class<V> type() {
return (Class<V>) attributes.get( attributes.size() - 1 ).type();
return (Class<V>) attributes.getLast().type();
}

/**
Expand All @@ -152,7 +171,7 @@ public <V extends Comparable<? super V>> Class<V> type() {
* @param ignoreCase instruction to ignore character case for comparison operations.
* @return New attribute with flag set.
*/
Attribute ignoreCase( boolean ignoreCase ) {
Attribute ignoreCase( final boolean ignoreCase ) {
return toBuilder().ignoreCase( ignoreCase )
.build();
}
Expand Down Expand Up @@ -226,11 +245,11 @@ private boolean typeIsLong() {
return type() == Long.class || type() == long.class;
}

public List<? extends Comparable<?>> verify( List<? extends Comparable<?>> values ) {
public List<? extends Comparable<?>> verify( final List<? extends Comparable<?>> values ) {
return values.stream().map( this::verify ).toList();
}

public Comparable<?>[] verify( Comparable<?>... values ) {
public Comparable<?>[] verify( final Comparable<?>... values ) {
return Arrays.stream( values ).map( this::verify ).toArray( Comparable<?>[]::new );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static class FilterCreator {
* @param value the value to compare to
* @return the filter for the operation
*/
public Filter equalTo( Comparable<?> value ) {
public Filter equalTo( final Comparable<?> value ) {
return Filter.create( f -> f.attribute( attribute ).equalTo( attribute.verify( value ) ) );
}

Expand All @@ -29,7 +29,7 @@ public Filter equalTo( Comparable<?> value ) {
* @param values the value to compare to
* @return the filter for the operation
*/
public Filter equalTo( List<? extends Comparable<?>> values ) {
public Filter equalTo( final List<? extends Comparable<?>> values ) {
return Filter.create( f -> f.attribute( attribute ).equalTo( attribute.verify( values ) ) );
}

Expand All @@ -39,7 +39,7 @@ public Filter equalTo( List<? extends Comparable<?>> values ) {
* @param values the value to compare to
* @return the filter for the operation
*/
public Filter in( List<? extends Comparable<?>> values ) {
public Filter in( final List<? extends Comparable<?>> values ) {
return Filter.create( f -> f.attribute( attribute ).in( attribute.verify( values ) ) );
}

Expand All @@ -49,7 +49,7 @@ public Filter in( List<? extends Comparable<?>> values ) {
* @param values the value to compare to
* @return the filter for the operation
*/
public Filter in( Comparable<?>... values ) {
public Filter in( final Comparable<?>... values ) {
return Filter.create( f -> f.attribute( attribute ).in( attribute.verify( values ) ) );
}

Expand All @@ -59,7 +59,7 @@ public Filter in( Comparable<?>... values ) {
* @param values the value to compare to
* @return the filter for the operation
*/
public Filter like( String... values ) {
public Filter like( final String... values ) {
return Filter.create( f -> f.attribute( attribute ).like( attribute.verify( values ) ) );
}

Expand All @@ -69,7 +69,7 @@ public Filter like( String... values ) {
* @param values the value to compare to
* @return the filter for the operation
*/
public Filter like( List<? extends Comparable<?>> values ) {
public Filter like( final List<? extends Comparable<?>> values ) {
return Filter.create( f -> f.attribute( attribute ).like( attribute.verify( values ) ) );
}

Expand All @@ -79,7 +79,7 @@ public Filter like( List<? extends Comparable<?>> values ) {
* @param value The value to compare to
* @return A filter for the operation
*/
public Filter greaterThan( Comparable<?> value ) {
public Filter greaterThan( final Comparable<?> value ) {
return Filter.create( f -> f.attribute( attribute ).greaterThan( attribute.verify( value ) ) );
}

Expand All @@ -99,7 +99,7 @@ public Filter greaterThan( final List<? extends Comparable<?>> values ) {
* @param value The value to compare to
* @return A filter for the operation
*/
public Filter lessThan( Comparable<?> value ) {
public Filter lessThan( final Comparable<?> value ) {
return Filter.create( f -> f.attribute( attribute ).lessThan( attribute.verify( value ) ) );
}

Expand All @@ -109,7 +109,7 @@ public Filter lessThan( Comparable<?> value ) {
* @param values values to compare
* @return A filter for the operation
*/
public Filter lessThan( List<? extends Comparable<?>> values ) {
public Filter lessThan( final List<? extends Comparable<?>> values ) {
return Filter.create( f -> f.attribute( attribute ).lessThan( attribute.verify( values ) ) );
}
}
Expand All @@ -134,54 +134,54 @@ public static FilterCreator attribute( final Attribute attribute ) {
* @param type of the attribute to be filtered on
* @return the filter creator for the operation
*/
public static FilterCreator attribute( final String name, Class<? extends Comparable<?>> type ) {
public static FilterCreator attribute( final String name, final Class<? extends Comparable<?>> type ) {
return FilterCreator.create( Attribute.of( name, type ) );
}

/**
* Starts filter-creation with a path of the provided attributes
* Starts filter-creation with a of of the provided attributes
*
* @param name1 of the first attribute in the path
* @param type1 of the first attribute in the path
* @param name2 of the second attribute in the path
* @param type2 of the second attribute in the path
* @param name1 of the first attribute in the of
* @param type1 of the first attribute in the of
* @param name2 of the second attribute in the of
* @param type2 of the second attribute in the of
* @return the filter creator for the operation
*/
public static FilterCreator attribute( final String name1, Class<? extends Comparable<?>> type1, String name2,
Class<? extends Comparable<?>> type2 ) {
return FilterCreator.create( Attribute.path( name1, type1, name2, type2 ) );
public static FilterCreator attribute( final String name1, final Class<? extends Comparable<?>> type1,
final String name2, final Class<? extends Comparable<?>> type2 ) {
return FilterCreator.create( Attribute.of( name1, type1, name2, type2 ) );
}

/**
* Starts filter-creation with a path of the provided attributes
* Starts filter-creation with a of of the provided attributes
*/
public static FilterCreator attribute( final jakarta.persistence.metamodel.Attribute<?, ?>... path ) {
return attribute( Attribute.path( path ) );
return attribute( Attribute.of( path ) );
}

/**
* Starts filter-creation with a path of the provided attributes
* Starts filter-creation with a of of the provided attributes
*/
public static FilterCreator attribute( final SingularAttribute<?, ? extends Comparable<?>> attribute ) {
return attribute( Attribute.of( attribute ) );
}

/**
* Starts filter-creation with a path of the provided attributes, ignoring the case in the subsequent operations.
* Starts filter-creation with a of of the provided attributes, ignoring the case in the subsequent operations.
*/
public static FilterCreator ignoreCase( final Attribute attribute ) {
return FilterCreator.create( attribute.withIgnoreCase() );
}

/**
* Starts filter-creation with a path of the provided attributes, ignoring the case in the subsequent operations.
* Starts filter-creation with a of of the provided attributes, ignoring the case in the subsequent operations.
*/
public static FilterCreator ignoreCase( final jakarta.persistence.metamodel.Attribute<?, ?>... path ) {
return ignoreCase( Attribute.path( path ) );
return ignoreCase( Attribute.of( path ) );
}

/**
* Starts filter-creation with a path of the provided attributes, ignoring the case in the subsequent operations.
* Starts filter-creation with a of of the provided attributes, ignoring the case in the subsequent operations.
*/
public static FilterCreator ignoreCase( final SingularAttribute<?, ? extends Comparable<?>> attribute ) {
return ignoreCase( Attribute.of( attribute ) );
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.vigier.cursorpaging.jpa;

import lombok.EqualsAndHashCode;
import java.util.Objects;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;

/**
Expand Down Expand Up @@ -28,6 +28,8 @@ public static SingleAttribute of( final String name, final Class<?> type ) {
* @return the new instance.
*/
public static SingleAttribute of( final jakarta.persistence.metamodel.Attribute<?, ?> attribute ) {
Objects.requireNonNull( attribute, "Attribute must not be null: JPA metamodel might not be initialized, "
+ "make sure the entity manager is created." );
return new SingleAttribute( attribute.getName(), attribute.getJavaType() );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ public FilterBuilder attribute( final Attribute attribute ) {
}

/**
* Creates an attribute as path to an embedded entity's property.
* Creates an attribute as path to an embedded/related entity's property.
*
* @param attributes the path to the property
* @param attributes the of to the property
* @return the builder
*/
@SafeVarargs
public final FilterBuilder path(
final jakarta.persistence.metamodel.Attribute<?, ? extends Comparable<?>>... attributes ) {
this.attribute = Attribute.path( attributes );
this.attribute = Attribute.of( attributes );
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@ void shouldCreateFilterFromManualSpecifiedAttributeWithMultipleValues() {

@Test
void shouldCreateFilterFromPath() {
Long value = 4711L;
final Long value = 4711L;
final var sut = Filter.create(
f -> f.attribute( Attribute.path( DataRecord_.TAGS, Set.class, Tag_.ID, Long.class ) )
.equalTo( value ) );
f -> f.attribute( Attribute.of( DataRecord_.TAGS, Set.class, Tag_.ID, Long.class ) ).equalTo( value ) );
verifyNameAndValue( sut, DataRecord_.TAGS + "." + Tag_.ID, Long.class, value );
}

Expand All @@ -77,19 +76,21 @@ void shouldBeEqual() {
shouldBeEqual( f1 -> f1.lessThan( "1L" ), f2 -> f2.lessThan( "1L" ) );
}

private void shouldBeEqual( Function<FilterCreator, Filter> f1, Function<FilterCreator, Filter> f2 ) {
var name1 = Attribute.of( "name", String.class );
var name2 = Attribute.of( "name", String.class );
private void shouldBeEqual( final Function<FilterCreator, Filter> f1, final Function<FilterCreator, Filter> f2 ) {
final var name1 = Attribute.of( "name", String.class );
final var name2 = Attribute.of( "name", String.class );

Assertions.assertThat( f1.apply( Filters.attribute( name1 ) ) )
.isEqualTo( f2.apply( Filters.attribute( name2 ) ) );
}

@Test
void filterListsShouldBeEqual() {
var nameAndAge1 = Filters.and( Filters.attribute( Attribute.of( "name", String.class ) ).equalTo( "John" ),
final var nameAndAge1 = Filters.and(
Filters.attribute( Attribute.of( "name", String.class ) ).equalTo( "John" ),
Filters.attribute( Attribute.of( "age", Long.class ) ).equalTo( 18 ) );
var nameAndAge2 = Filters.and( Filters.attribute( Attribute.of( "name", String.class ) ).equalTo( "John" ),
final var nameAndAge2 = Filters.and(
Filters.attribute( Attribute.of( "name", String.class ) ).equalTo( "John" ),
Filters.attribute( Attribute.of( "age", Long.class ) ).equalTo( 18 ) );

Assertions.assertThat( nameAndAge1 ).isEqualTo( nameAndAge2 );
Expand Down
Loading

0 comments on commit 17e43a2

Please sign in to comment.