From 5380467824e2c3cc6fd53c8ac7208e65fcb1143e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 4 Sep 2019 16:44:47 +0200 Subject: [PATCH 1/2] HSEARCH-3690 Add a default identifier bridge for the String type in the POJO mapper --- .../impl/DefaultStringIdentifierBridge.java | 29 +++++++++++++++++++ .../bridge/mapping/impl/BridgeResolver.java | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/builtin/impl/DefaultStringIdentifierBridge.java diff --git a/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/builtin/impl/DefaultStringIdentifierBridge.java b/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/builtin/impl/DefaultStringIdentifierBridge.java new file mode 100644 index 00000000000..051e46ba3c7 --- /dev/null +++ b/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/builtin/impl/DefaultStringIdentifierBridge.java @@ -0,0 +1,29 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.mapper.pojo.bridge.builtin.impl; + +import org.hibernate.search.mapper.pojo.bridge.IdentifierBridge; +import org.hibernate.search.mapper.pojo.bridge.runtime.IdentifierBridgeFromDocumentIdentifierContext; +import org.hibernate.search.mapper.pojo.bridge.runtime.IdentifierBridgeToDocumentIdentifierContext; + +public final class DefaultStringIdentifierBridge implements IdentifierBridge { + + @Override + public String toDocumentIdentifier(String propertyValue, IdentifierBridgeToDocumentIdentifierContext context) { + return propertyValue; + } + + @Override + public String fromDocumentIdentifier(String documentIdentifier, IdentifierBridgeFromDocumentIdentifierContext context) { + return documentIdentifier; + } + + @Override + public boolean isCompatibleWith(IdentifierBridge other) { + return getClass().equals( other.getClass() ); + } +} diff --git a/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/mapping/impl/BridgeResolver.java b/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/mapping/impl/BridgeResolver.java index ede1912e354..7f9d964c73f 100644 --- a/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/mapping/impl/BridgeResolver.java +++ b/mapper/pojo/src/main/java/org/hibernate/search/mapper/pojo/bridge/mapping/impl/BridgeResolver.java @@ -57,6 +57,7 @@ import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultLongIdentifierBridge; import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultPeriodValueBridge; import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultShortIdentifierBridge; +import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultStringIdentifierBridge; import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultUUIDIdentifierBridge; import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultUUIDValueBridge; import org.hibernate.search.mapper.pojo.bridge.builtin.impl.DefaultZoneIdValueBridge; @@ -89,6 +90,7 @@ public BridgeResolver(TypePatternMatcherFactory typePatternMatcherFactory) { TypePatternMatcher concreteGeoPointPattern = typePatternMatcherFactory.createRawSuperTypeMatcher( GeoPoint.class ); + addIdentifierBridgeForExactRawType( String.class, new DefaultStringIdentifierBridge() ); addIdentifierBridgeForExactRawType( Integer.class, new DefaultIntegerIdentifierBridge() ); addIdentifierBridgeForExactRawType( Long.class, new DefaultLongIdentifierBridge() ); addIdentifierBinderForTypePattern( concreteEnumPattern, new DefaultEnumIdentifierBridge.Binder() ); From 6a82cfcf28042da462e1cafcaa4b8952204d7f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoann=20Rodi=C3=A8re?= Date: Wed, 4 Sep 2019 16:44:18 +0200 Subject: [PATCH 2/2] HSEARCH-3690 Test String properties more extensively for the POJO mapper --- .../definition/IndexNullAsErrorIT.java | 7 +- .../types/PropertyTypeDescriptor.java | 1 + .../types/StringPropertyTypeDescriptor.java | 177 ++++++++++++++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/StringPropertyTypeDescriptor.java diff --git a/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/mapping/definition/IndexNullAsErrorIT.java b/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/mapping/definition/IndexNullAsErrorIT.java index fb8a0906b76..a01d47eca11 100644 --- a/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/mapping/definition/IndexNullAsErrorIT.java +++ b/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/mapping/definition/IndexNullAsErrorIT.java @@ -16,6 +16,7 @@ import org.hibernate.search.util.impl.integrationtest.common.rule.BackendMock; import org.hibernate.search.util.impl.test.SubTest; +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,13 +52,17 @@ public IndexNullAsErrorIT(PropertyTypeDescriptor typeDescriptor, Optional setupHelper.start().withConfiguration( c -> c .addEntityType( expectations.getTypeWithValueBridge1() ) .programmaticMapping() .type( expectations.getTypeWithValueBridge1() ).indexed() .property( FIELD_NAME ).genericField( FIELD_NAME ) - .property( FIELD_NAME ).genericField( FIELD_INDEXNULLAS_NAME ).indexNullAs( expectations.getUnparsableNullAsValue() ) + .property( FIELD_NAME ).genericField( FIELD_INDEXNULLAS_NAME ).indexNullAs( unparsableNullAsValue ) ).setup() ) .assertThrown() diff --git a/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/PropertyTypeDescriptor.java b/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/PropertyTypeDescriptor.java index 26b26541088..da5301f05c7 100644 --- a/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/PropertyTypeDescriptor.java +++ b/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/PropertyTypeDescriptor.java @@ -21,6 +21,7 @@ public abstract class PropertyTypeDescriptor { public static List> getAll() { if ( all == null ) { all = Collections.unmodifiableList( Arrays.asList( + new StringPropertyTypeDescriptor(), new BoxedIntegerPropertyTypeDescriptor(), new BoxedLongPropertyTypeDescriptor(), new BoxedBooleanPropertyTypeDescriptor(), diff --git a/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/StringPropertyTypeDescriptor.java b/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/StringPropertyTypeDescriptor.java new file mode 100644 index 00000000000..c1ddb7d7375 --- /dev/null +++ b/integrationtest/mapper/pojo/src/test/java/org/hibernate/search/integrationtest/mapper/pojo/testsupport/types/StringPropertyTypeDescriptor.java @@ -0,0 +1,177 @@ +/* + * Hibernate Search, full-text search for your domain model + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.search.integrationtest.mapper.pojo.testsupport.types; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.hibernate.search.integrationtest.mapper.pojo.testsupport.types.expectations.DefaultIdentifierBridgeExpectations; +import org.hibernate.search.integrationtest.mapper.pojo.testsupport.types.expectations.DefaultValueBridgeExpectations; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.DocumentId; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.GenericField; +import org.hibernate.search.mapper.pojo.mapping.definition.annotation.Indexed; + +public class StringPropertyTypeDescriptor extends PropertyTypeDescriptor { + + StringPropertyTypeDescriptor() { + super( String.class ); + } + + @Override + public Optional> getDefaultIdentifierBridgeExpectations() { + return Optional.of( new DefaultIdentifierBridgeExpectations() { + @Override + public List getEntityIdentifierValues() { + return Arrays.asList( "", "a", "AaaA", "Some words", "\000", "http://foo", "yop@yopmail.com" ); + } + + @Override + public List getDocumentIdentifierValues() { + return getEntityIdentifierValues(); + } + + @Override + public Class getTypeWithIdentifierBridge1() { + return TypeWithIdentifierBridge1.class; + } + + @Override + public Object instantiateTypeWithIdentifierBridge1(String identifier) { + TypeWithIdentifierBridge1 instance = new TypeWithIdentifierBridge1(); + instance.id = identifier; + return instance; + } + + @Override + public Class getTypeWithIdentifierBridge2() { + return TypeWithIdentifierBridge2.class; + } + } ); + } + + @Override + public Optional> getDefaultValueBridgeExpectations() { + return Optional.of( new DefaultValueBridgeExpectations() { + @Override + public Class getProjectionType() { + return String.class; + } + + @Override + public Class getIndexFieldJavaType() { + return String.class; + } + + @Override + public List getEntityPropertyValues() { + return Arrays.asList( "", "a", "AaaA", "Some words", "\000", "http://foo", "yop@yopmail.com" ); + } + + @Override + public List getDocumentFieldValues() { + return getEntityPropertyValues(); + } + + @Override + public Class getTypeWithValueBridge1() { + return TypeWithValueBridge1.class; + } + + @Override + public Object instantiateTypeWithValueBridge1(int identifier, String propertyValue) { + TypeWithValueBridge1 instance = new TypeWithValueBridge1(); + instance.id = identifier; + instance.myProperty = propertyValue; + return instance; + } + + @Override + public Class getTypeWithValueBridge2() { + return TypeWithValueBridge2.class; + } + + @Override + public String getNullAsValueBridge1() { + return ""; + } + + @Override + public String getNullAsValueBridge2() { + return "some value"; + } + + @Override + public String getUnparsableNullAsValue() { + // Every string is valid + return null; + } + } ); + } + + @Indexed(index = DefaultIdentifierBridgeExpectations.TYPE_WITH_IDENTIFIER_BRIDGE_1_INDEX_NAME) + public static class TypeWithIdentifierBridge1 { + String id; + @DocumentId + public String getId() { + return id; + } + } + + @Indexed(index = DefaultIdentifierBridgeExpectations.TYPE_WITH_IDENTIFIER_BRIDGE_2_INDEX_NAME) + public static class TypeWithIdentifierBridge2 { + String id; + @DocumentId + public String getId() { + return id; + } + } + + @Indexed(index = DefaultValueBridgeExpectations.TYPE_WITH_VALUE_BRIDGE_1_INDEX_NAME) + public static class TypeWithValueBridge1 { + Integer id; + String myProperty; + String indexNullAsProperty; + + @DocumentId + public Integer getId() { + return id; + } + + @GenericField + public String getMyProperty() { + return myProperty; + } + + @GenericField(indexNullAs = "") + public String getIndexNullAsProperty() { + return indexNullAsProperty; + } + } + + @Indexed(index = DefaultValueBridgeExpectations.TYPE_WITH_VALUE_BRIDGE_2_INDEX_NAME) + public static class TypeWithValueBridge2 { + Integer id; + String myProperty; + String indexNullAsProperty; + + @DocumentId + public Integer getId() { + return id; + } + + @GenericField + public String getMyProperty() { + return myProperty; + } + + @GenericField(indexNullAs = "some value") + public String getIndexNullAsProperty() { + return indexNullAsProperty; + } + } +}