Created
October 9, 2016 22:09
-
-
Save elucash/a701a64ce608de6c6780052ab3b1eb00 to your computer and use it in GitHub Desktop.
Resolves public constructors in spring data. But hard to plug this into configuration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package springhack; | |
import java.lang.annotation.Annotation; | |
import java.util.List; | |
import org.springframework.data.mapping.PersistentEntity; | |
import org.springframework.data.mapping.PreferredConstructor.Parameter; | |
import java.lang.reflect.Constructor; | |
import java.lang.reflect.Modifier; | |
import org.springframework.beans.BeansException; | |
import org.springframework.context.ApplicationContext; | |
import org.springframework.core.DefaultParameterNameDiscoverer; | |
import org.springframework.core.ParameterNameDiscoverer; | |
import org.springframework.data.mapping.PersistentProperty; | |
import org.springframework.data.mapping.PreferredConstructor; | |
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; | |
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; | |
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; | |
import org.springframework.data.util.TypeInformation; | |
public class OverrideMongoMappingContext extends MongoMappingContext { | |
private ApplicationContext applicationContext; | |
@Override | |
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { | |
this.applicationContext = applicationContext; | |
super.setApplicationContext(applicationContext); | |
} | |
@Override | |
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) { | |
OverrideBasicMongoPersistentEntity<T> entity = new OverrideBasicMongoPersistentEntity<>(typeInformation); | |
if (applicationContext != null) { | |
entity.setApplicationContext(applicationContext); | |
} | |
return entity; | |
} | |
public static class OverrideBasicMongoPersistentEntity<T> extends BasicMongoPersistentEntity<T> { | |
private final ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer(); | |
private final TypeInformation<T> type; | |
private final PreferredConstructor<T, MongoPersistentProperty> constructor; | |
public OverrideBasicMongoPersistentEntity(TypeInformation<T> type) { | |
super(type); | |
this.type = type; | |
// new PreferredConstructorDiscoverer<>(null) | |
this.constructor = discoverConstructor(); | |
} | |
private PreferredConstructor<T, MongoPersistentProperty> discoverConstructor() { | |
Class<?> rawOwningType = type.getType(); | |
for (Constructor<?> candidate : rawOwningType.getDeclaredConstructors()) { | |
if (Modifier.isPublic(candidate.getModifiers())) { | |
return buildPreferredConstructor(candidate, type, this); | |
} | |
} | |
return null; | |
} | |
@SuppressWarnings({"unchecked", "rawtypes"}) | |
private PreferredConstructor<T, MongoPersistentProperty> buildPreferredConstructor( | |
Constructor<?> constructor, | |
TypeInformation<T> typeInformation, | |
PersistentEntity<T, MongoPersistentProperty> entity) { | |
List<TypeInformation<?>> parameterTypes = typeInformation.getParameterTypes(constructor); | |
if (parameterTypes.isEmpty()) { | |
return new PreferredConstructor<>((Constructor<T>) constructor); | |
} | |
String[] parameterNames = discoverer.getParameterNames(constructor); | |
Parameter<Object, MongoPersistentProperty>[] parameters = new Parameter[parameterTypes.size()]; | |
Annotation[][] parameterAnnotations = constructor.getParameterAnnotations(); | |
for (int i = 0; i < parameterTypes.size(); i++) { | |
String name = parameterNames == null ? null : parameterNames[i]; | |
TypeInformation<?> type = parameterTypes.get(i); | |
Annotation[] annotations = parameterAnnotations[i]; | |
parameters[i] = new Parameter(name, type, annotations, entity); | |
} | |
return new PreferredConstructor<>((Constructor<T>) constructor, parameters); | |
} | |
@Override | |
public boolean isConstructorArgument(PersistentProperty<?> property) { | |
return constructor == null ? false : constructor.isConstructorParameter(property); | |
} | |
@Override | |
public PreferredConstructor<T, MongoPersistentProperty> getPersistenceConstructor() { | |
return constructor; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment