As part of HSEARCH-175, we added support for domain specific annotations for {{TypeBridge}} and {{PropertyBridge}}, but not for {{ValueBridge}} yet. I can't think of a reason why users shouldn't be able to do that, so let's try to add support for it?
Note: we will still need to allow value bridges to be used directly with the standard {{@Field}} annotation.
The difficulty main challenge is that, when applying a value bridge, we need to pass information to Hibernate Search to tell it how to apply the bridge: the reference to the bridge, but also the field name, the container extractor, ... User-defined annotations would have to take this into account.
One solution would be to stick to what we've already done, add an {{initialize(A annotation)}} method to {{ValueBinder}} as well as a few methods to get the field name and container extractor path from the binder.
Another, perhaps better, and definitely more powerful solution would be to create a separate, dedicated mechanism for annotation processing. We could just introduce a {{MappingAnnotationProcessor}} interface that is responsible for reading an annotation and translating it into a programmatic mapping, e.g.:
{code} @MappingAnnotation(processor = MyMappingAnnotationProcessor.class) public @interface MyMapping {
// Custom attributes String foo();
// Custom attributes that use a standard type, we'll provide helpers to process them ContainerExtraction extraction() default @ContainerExtraction;
}
public class MyMappingAnnotationProcessor implements MappingAnnotationProcessor<MyMapping> {
// We'll need either multiple processor interfaces, // or multiple methods defaulting to no-op: // one per annotation target (Type, property, something else?) public void process(MyMapping annotation, MappingAnnotationPropertyContext context) { // getProperty() would return a PropertyMappingStep context.getProperty().genericField( annotation.foo() ) .containerExtractors( context.toContainerExtractorPath( annotation.extraction() ) .valueBinder( new MyValueBinder() ); // Or maybe provide more direct helpers: context.genericField( annotation.foo(), annotation.extraction() ) .valueBinder( new MyValueBinder() ); }
} {code}
Pros of that second solution:
* Very powerful. Could be used for much more than just value bridges. * Could be used to implement most (all?) mapping annotations. * Could be used to implement support for Search 5 annotations: we'd just need to annotate these with {{@MappingAnnotation}} and provide the appropriate processor.
Cons:
* More complex than stuffing everything into the binder, since users now need to implement four types: the bridge, the binder, the annotation, and the annotation processor. * Would make the current annotation mechanism for {{TypeBinder}}/{{PropertyBinder}} obsolete, so we should probably deprecate and ultimately remove it. This will require a breaking change, since both types have a generic type parameter for the annotation type. |
|