SGF-402 - Add SDG Annotation configuration support for Lucene Integration.
(cherry picked from commit 249e64586537d9be9331971b9e3b3d864b6cf694) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -206,6 +206,11 @@ public class EntityDefinedRegionsConfiguration
|
||||
return importingClassMetadata.hasAnnotation(annotationName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected AnnotationAttributes getAnnotationAttributes(Annotation annotation) {
|
||||
return AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(annotation));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected AnnotationAttributes getAnnotationAttributes(AnnotationMetadata importingClassMetadata) {
|
||||
return getAnnotationAttributes(importingClassMetadata, getAnnotationTypeName());
|
||||
|
||||
@@ -21,6 +21,8 @@ import java.lang.annotation.Annotation;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.lucene.LuceneIndex;
|
||||
import org.apache.geode.cache.query.Index;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
@@ -33,13 +35,15 @@ import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentProperty;
|
||||
import org.springframework.data.gemfire.mapping.annotation.Indexed;
|
||||
import org.springframework.data.gemfire.mapping.annotation.LuceneIndexed;
|
||||
import org.springframework.data.gemfire.search.lucene.LuceneIndexFactoryBean;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* The {@link IndexConfiguration} class is a Spring {@link org.springframework.context.annotation.ImportBeanDefinitionRegistrar}
|
||||
* and extension of {@link EntityDefinedRegionsConfiguration} used in the {@link EnableIndexes} annotation
|
||||
* to dynamically create GemFire/Geode {@link org.apache.geode.cache.Region} Indexes based on
|
||||
* to dynamically create GemFire/Geode {@link org.apache.geode.cache.Region} {@link Index Indexes} based on
|
||||
* {@link GemfirePersistentEntity} {@link GemfirePersistentProperty} annotations.
|
||||
*
|
||||
* @author John Blum
|
||||
@@ -49,11 +53,13 @@ import org.springframework.util.StringUtils;
|
||||
* @see org.springframework.data.annotation.Id
|
||||
* @see org.springframework.data.gemfire.IndexFactoryBean
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
* @see org.springframework.data.gemfire.search.lucene.LuceneIndexFactoryBean
|
||||
* @see org.springframework.data.gemfire.config.annotation.EntityDefinedRegionsConfiguration
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentProperty
|
||||
* @see Indexed
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.Indexed
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.lucene.LuceneIndex
|
||||
* @see org.apache.geode.cache.query.Index
|
||||
* @since 1.9.0
|
||||
*/
|
||||
@@ -105,9 +111,9 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
|
||||
*/
|
||||
@Override
|
||||
protected GemfirePersistentEntity<?> postProcess(AnnotationMetadata importingClassMetadata,
|
||||
final BeanDefinitionRegistry registry, GemfirePersistentEntity<?> persistentEntity) {
|
||||
BeanDefinitionRegistry registry, GemfirePersistentEntity<?> persistentEntity) {
|
||||
|
||||
final GemfirePersistentEntity<?> localPersistentEntity =
|
||||
GemfirePersistentEntity<?> localPersistentEntity =
|
||||
super.postProcess(importingClassMetadata, registry, persistentEntity);
|
||||
|
||||
if (isAnnotationPresent(importingClassMetadata, getEnableIndexesAnnotationTypeName())) {
|
||||
@@ -115,16 +121,17 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
|
||||
getAnnotationAttributes(importingClassMetadata, getEnableIndexesAnnotationTypeName());
|
||||
|
||||
localPersistentEntity.doWithProperties((PropertyHandler<GemfirePersistentProperty>) persistentProperty -> {
|
||||
Optional<Id> idAnnotation = persistentProperty.findAnnotation(Id.class);
|
||||
persistentProperty.findAnnotation(Id.class).ifPresent(idAnnotation ->
|
||||
registerIndexBeanDefinition(enableIndexesAttributes, localPersistentEntity, persistentProperty,
|
||||
IndexType.KEY, idAnnotation, registry));
|
||||
|
||||
idAnnotation.ifPresent(id -> registerIndexBeanDefinition(enableIndexesAttributes, localPersistentEntity,
|
||||
persistentProperty, IndexType.KEY, id, registry));
|
||||
persistentProperty.findAnnotation(Indexed.class).ifPresent(indexedAnnotation ->
|
||||
registerIndexBeanDefinition(enableIndexesAttributes, localPersistentEntity, persistentProperty,
|
||||
indexedAnnotation.type(), indexedAnnotation, registry));
|
||||
|
||||
Optional<Indexed> indexedAnnotation = persistentProperty.findAnnotation(Indexed.class);
|
||||
|
||||
indexedAnnotation.ifPresent(
|
||||
indexed -> registerIndexBeanDefinition(enableIndexesAttributes, localPersistentEntity,
|
||||
persistentProperty, indexed.type(), indexed, registry));
|
||||
persistentProperty.findAnnotation(LuceneIndexed.class).ifPresent( luceneIndexAnnotation ->
|
||||
registerLuceneIndexBeanDefinition(enableIndexesAttributes, localPersistentEntity,
|
||||
persistentProperty, luceneIndexAnnotation, registry));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -150,38 +157,87 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentProperty
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void registerIndexBeanDefinition(AnnotationAttributes enableIndexesAttributes,
|
||||
GemfirePersistentEntity<?> persistentEntity, GemfirePersistentProperty persistentProperty,
|
||||
IndexType indexType, Annotation indexAnnotation, BeanDefinitionRegistry registry) {
|
||||
|
||||
if (indexAnnotation != null) {
|
||||
AnnotationAttributes indexAnnotationAttributes = AnnotationAttributes.fromMap(
|
||||
AnnotationUtils.getAnnotationAttributes(indexAnnotation));
|
||||
Optional.ofNullable(indexAnnotation).ifPresent(localIndexAnnotation -> {
|
||||
AnnotationAttributes indexedAttributes = getAnnotationAttributes(localIndexAnnotation);
|
||||
|
||||
BeanDefinitionBuilder indexFactoryBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(IndexFactoryBean.class);
|
||||
|
||||
String indexName = resolveName(persistentEntity, persistentProperty,
|
||||
indexAnnotationAttributes, indexType);
|
||||
String indexName = resolveName(persistentEntity, persistentProperty, indexedAttributes, indexType);
|
||||
|
||||
indexFactoryBeanBuilder.addPropertyReference("cache", GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
|
||||
indexFactoryBeanBuilder.addPropertyValue("define", resolveDefine(enableIndexesAttributes));
|
||||
|
||||
indexFactoryBeanBuilder.addPropertyValue("expression",
|
||||
resolveExpression(persistentEntity, persistentProperty, indexAnnotationAttributes));
|
||||
resolveExpression(persistentEntity, persistentProperty, indexedAttributes));
|
||||
|
||||
indexFactoryBeanBuilder.addPropertyValue("from",
|
||||
resolveFrom(persistentEntity, persistentProperty, indexAnnotationAttributes));
|
||||
resolveFrom(persistentEntity, persistentProperty, indexedAttributes));
|
||||
|
||||
indexFactoryBeanBuilder.addPropertyValue("name", indexName);
|
||||
|
||||
/*
|
||||
indexFactoryBeanBuilder.addPropertyValue("override",
|
||||
resolveOverride(persistentEntity, persistentProperty, indexedAttributes));
|
||||
*/
|
||||
|
||||
indexFactoryBeanBuilder.addPropertyValue("type",
|
||||
resolveType(persistentEntity, persistentProperty, indexAnnotationAttributes, indexType).toString());
|
||||
resolveType(persistentEntity, persistentProperty, indexedAttributes, indexType).toString());
|
||||
|
||||
registry.registerBeanDefinition(indexName, indexFactoryBeanBuilder.getBeanDefinition());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link LuceneIndex} for the {@link GemfirePersistentProperty} on the {@link GemfirePersistentEntity}
|
||||
* using the {@link Annotation} meta-data to define the Index.
|
||||
*
|
||||
* @param enableIndexesAttributes {@link AnnotationAttributes} containing meta-data
|
||||
* for the {@link EnableIndexes} annotation.
|
||||
* @param persistentEntity {@link GemfirePersistentEntity} containing the {@link GemfirePersistentProperty}
|
||||
* to be indexed.
|
||||
* @param persistentProperty {@link GemfirePersistentProperty} for which the {@link LuceneIndex} will be created.
|
||||
* @param luceneIndexAnnotation {@link LuceneIndexed} {@link Annotation}.
|
||||
* @param registry {@link BeanDefinitionRegistry} used to register the {@link LuceneIndex} bean definition.
|
||||
* @see java.lang.annotation.Annotation
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentEntity
|
||||
* @see org.springframework.data.gemfire.mapping.GemfirePersistentProperty
|
||||
* @see org.springframework.data.gemfire.mapping.annotation.LuceneIndexed
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void registerLuceneIndexBeanDefinition(AnnotationAttributes enableIndexesAttributes,
|
||||
GemfirePersistentEntity<?> persistentEntity, GemfirePersistentProperty persistentProperty,
|
||||
Annotation luceneIndexAnnotation, BeanDefinitionRegistry registry) {
|
||||
|
||||
Optional.ofNullable(luceneIndexAnnotation).ifPresent(localLuceneIndexAnnotation -> {
|
||||
AnnotationAttributes luceneIndexAttributes =
|
||||
AnnotationAttributes.fromMap(AnnotationUtils.getAnnotationAttributes(localLuceneIndexAnnotation));
|
||||
|
||||
BeanDefinitionBuilder luceneIndexFactoryBeanBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(LuceneIndexFactoryBean.class);
|
||||
|
||||
String indexName = luceneIndexAttributes.getString("name");
|
||||
|
||||
boolean destroy = (luceneIndexAttributes.containsKey("destroy")
|
||||
&& luceneIndexAttributes.getBoolean("destroy"));
|
||||
|
||||
luceneIndexFactoryBeanBuilder.addPropertyValue("destroy", destroy);
|
||||
|
||||
luceneIndexFactoryBeanBuilder.addPropertyValue("fields", persistentProperty.getName());
|
||||
|
||||
luceneIndexFactoryBeanBuilder.addPropertyValue("indexName", indexName);
|
||||
|
||||
luceneIndexFactoryBeanBuilder.addPropertyValue("regionPath", persistentEntity.getRegionName());
|
||||
|
||||
registry.registerBeanDefinition(indexName, luceneIndexFactoryBeanBuilder.getBeanDefinition());
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@@ -193,10 +249,10 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unused")
|
||||
private String resolveExpression(GemfirePersistentEntity<?> persistentEntity,
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexAnnotationAttributes) {
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexedAttributes) {
|
||||
|
||||
String expression = (indexAnnotationAttributes.containsKey("expression")
|
||||
? indexAnnotationAttributes.getString("expression") : null);
|
||||
String expression = (indexedAttributes.containsKey("expression")
|
||||
? indexedAttributes.getString("expression") : null);
|
||||
|
||||
return (StringUtils.hasText(expression) ? expression : persistentProperty.getName());
|
||||
}
|
||||
@@ -204,21 +260,20 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unused")
|
||||
private String resolveFrom(GemfirePersistentEntity<?> persistentEntity,
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexAnnotationAttributes) {
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexedAttributes) {
|
||||
|
||||
String from = (indexAnnotationAttributes.containsKey("from")
|
||||
? indexAnnotationAttributes.getString("from") : null);
|
||||
String from = (indexedAttributes.containsKey("from")
|
||||
? indexedAttributes.getString("from") : null);
|
||||
|
||||
return (StringUtils.hasText(from) ? from : persistentEntity.getRegionName());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private String resolveName(GemfirePersistentEntity<?> persistentEntity,
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexAnnotationAttributes,
|
||||
IndexType indexType) {
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexedAttributes, IndexType indexType) {
|
||||
|
||||
String indexName = (indexAnnotationAttributes.containsKey("name")
|
||||
? indexAnnotationAttributes.getString("name") : null);
|
||||
String indexName = (indexedAttributes.containsKey("name")
|
||||
? indexedAttributes.getString("name") : null);
|
||||
|
||||
return (StringUtils.hasText(indexName) ? indexName
|
||||
: generateIndexName(persistentEntity, persistentProperty, indexType));
|
||||
@@ -233,15 +288,25 @@ public class IndexConfiguration extends EntityDefinedRegionsConfiguration {
|
||||
StringUtils.capitalize(indexType.name().toLowerCase()));
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
/*
|
||||
@SuppressWarnings("unused")
|
||||
private boolean resolveOverride(GemfirePersistentEntity persistentEntity,
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexedAttributes) {
|
||||
|
||||
return (indexedAttributes.containsKey("override")
|
||||
&& indexedAttributes.getBoolean("override"));
|
||||
}
|
||||
*/
|
||||
|
||||
/* (non-Javadoc) */
|
||||
@SuppressWarnings("unused")
|
||||
private IndexType resolveType(GemfirePersistentEntity<?> persistentEntity,
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexAnnotationAttributes,
|
||||
IndexType indexType) {
|
||||
GemfirePersistentProperty persistentProperty, AnnotationAttributes indexedAttributes, IndexType indexType) {
|
||||
|
||||
IndexType resolvedIndexType = (indexAnnotationAttributes.containsKey("type")
|
||||
? indexAnnotationAttributes.getEnum("type") : null);
|
||||
IndexType resolvedIndexType = (indexedAttributes.containsKey("type")
|
||||
? indexedAttributes.getEnum("type") : null);
|
||||
|
||||
return (resolvedIndexType != null ? resolvedIndexType : indexType);
|
||||
return Optional.ofNullable(resolvedIndexType).orElse(indexType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.mapping.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.apache.geode.cache.lucene.LuceneIndex;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentProperty;
|
||||
|
||||
/**
|
||||
* The {@link LuceneIndexed} annotation is used to index a {@link GemfirePersistentEntity}
|
||||
* {@link GemfirePersistentProperty}, creating a GemFire/Geode {@link LuceneIndex}
|
||||
* on a GemFire/Geode {@link org.apache.geode.cache.Region}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.springframework.core.annotation.AliasFor
|
||||
* @see org.springframework.data.gemfire.IndexType
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.lucene.LuceneIndex
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
@SuppressWarnings("unused")
|
||||
public @interface LuceneIndexed {
|
||||
|
||||
/**
|
||||
* {@link String Name} of the {@link LuceneIndex}.
|
||||
*
|
||||
* @return a {@link String} containing the name of the {@link LuceneIndex}
|
||||
*/
|
||||
@AliasFor(attribute = "name")
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* {@link String Name} of the {@link LuceneIndex}.
|
||||
*
|
||||
* @return a {@link String} containing the name of the {@link LuceneIndex}
|
||||
*/
|
||||
@AliasFor(attribute = "value")
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* Determine whether the {@link LuceneIndex} should be destroy when the application shutsdown.
|
||||
*
|
||||
* Default is {@literal false}.
|
||||
*/
|
||||
boolean destroy() default false;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user