Skip to content

Instantly share code, notes, and snippets.

@athlan
Created September 22, 2015 19:30
Show Gist options
  • Save athlan/6497c74cc515131e1336 to your computer and use it in GitHub Desktop.
Save athlan/6497c74cc515131e1336 to your computer and use it in GitHub Desktop.
Spring Data Mongo custom _class value
package selly.spring.data.convert;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.convert.TypeInformationMapper;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
/**
* @author Piotr `Athlan` Pelczar
*/
public class AnnotationTypeInformationMapper implements TypeInformationMapper {
private final Map<ClassTypeInformation<?>, String> typeToAliasMap;
private final Map<String, ClassTypeInformation<?>> aliasToTypeMap;
private AnnotationTypeInformationMapper(List<String> basePackagesToScan) {
typeToAliasMap = new HashMap<>();
aliasToTypeMap = new HashMap<>();
populateTypeMap(basePackagesToScan);
}
private void populateTypeMap(List<String> basePackagesToScan) {
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(DocumentType.class));
for (String basePackage : basePackagesToScan) {
for (BeanDefinition bd : scanner.findCandidateComponents(basePackage)) {
try {
Class<?> clazz = Class.forName(bd.getBeanClassName());
DocumentType doumentTypeAnnotation = clazz.getAnnotation(DocumentType.class);
ClassTypeInformation<?> type = ClassTypeInformation.from(clazz);
String alias = doumentTypeAnnotation.value();
typeToAliasMap.put(type, alias);
aliasToTypeMap.put(alias, type);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(String.format("Class [%s] could not be loaded.", bd.getBeanClassName()), e);
}
}
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.convert.TypeInformationMapper#createAliasFor(org.springframework.data.util.TypeInformation)
*/
public Object createAliasFor(TypeInformation<?> type) {
ClassTypeInformation<?> typeClass = (ClassTypeInformation<?>) type;
if(typeToAliasMap.containsKey(typeClass)) {
return typeToAliasMap.get(typeClass);
}
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.convert.TypeInformationMapper#resolveTypeFrom(java.lang.Object)
*/
public ClassTypeInformation<?> resolveTypeFrom(Object alias) {
if(aliasToTypeMap.containsKey(alias)) {
return aliasToTypeMap.get(alias);
}
return null;
}
public static class Builder {
List<String> basePackagesToScan;
public Builder() {
basePackagesToScan = new ArrayList<>();
}
public Builder withBasePackage(String basePackage) {
basePackagesToScan.add(basePackage);
return this;
}
public Builder withBasePackages(String[] basePackages) {
basePackagesToScan.addAll(Arrays.asList(basePackages));
return this;
}
public Builder withBasePackages(Collection<? extends String> basePackages) {
basePackagesToScan.addAll(basePackages);
return this;
}
public AnnotationTypeInformationMapper build() {
AnnotationTypeInformationMapper builded = new AnnotationTypeInformationMapper(basePackagesToScan);
return builded;
}
}
}
package selly.spring.data.convert;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DocumentType {
public String value() default "";
}
package selly.service.auth.config;
import java.util.Arrays;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.convert.TypeInformationMapper;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoTypeMapper;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import selly.spring.data.convert.AnnotationTypeInformationMapper;
@Configuration
@EnableMongoRepositories(basePackages="selly")
public class AuthDataSourceConfiguration {
@Bean
public MongoClient mongoDbClient() throws Exception {
return new MongoClient(new ServerAddress("192.168.0.103"));
}
@Bean
public MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(mongoDbClient(), "selly_auth");
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
String[] basePackages = new String[] {"selly"};
TypeInformationMapper typeMapper1 = new AnnotationTypeInformationMapper.Builder().withBasePackages(basePackages).build();
MongoTypeMapper typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(typeMapper1));
MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
converter.setTypeMapper(typeMapper);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
return mongoTemplate;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment