com.github.aidensuen.mongo.provider.MongoProvider Maven / Gradle / Ivy
package com.github.aidensuen.mongo.provider;
import com.github.aidensuen.mongo.command.CommandSource;
import com.github.aidensuen.mongo.command.DynamicCommandSource;
import com.github.aidensuen.mongo.core.MongoDaoRepository;
import com.github.aidensuen.mongo.core.MongoDaoStatement;
import com.github.aidensuen.mongo.exception.MongoDaoException;
import com.github.aidensuen.mongo.exception.MongoProviderException;
import com.github.aidensuen.mongo.mapping.DynamicCommand;
import com.github.aidensuen.mongo.mapping.ExampleStr;
import com.github.aidensuen.mongo.util.MsUtil;
import com.github.aidensuen.util.ReflectionUtil;
import org.springframework.data.mongodb.core.query.Update;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public abstract class MongoProvider {
protected Map methodMap = new ConcurrentHashMap();
protected Map> entityClassMap = new ConcurrentHashMap>();
protected Class> mongoDaoClass;
protected MongoDaoRepository mongoDaoRepository;
public MongoProvider(Class> mongoDaoClass, MongoDaoRepository mongoDaoRepository) {
this.mongoDaoClass = mongoDaoClass;
this.mongoDaoRepository = mongoDaoRepository;
}
public Class> getEntityClass(MongoDaoStatement ms) {
String msId = ms.getId();
if (entityClassMap.containsKey(msId)) {
return entityClassMap.get(msId);
} else {
Class> mongoDaoClass = MsUtil.getMongoDaoClass(msId);
Type[] types = mongoDaoClass.getGenericInterfaces();
for (Type type : types) {
if (type instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType) type;
if (t.getRawType() == this.mongoDaoClass || this.mongoDaoClass.isAssignableFrom((Class>) t.getRawType())) {
Class> returnType = (Class>) t.getActualTypeArguments()[0];
entityClassMap.put(msId, returnType);
return returnType;
}
}
}
}
throw new MongoProviderException("can't get " + msId + " method's generic information!");
}
/**
* add method map
*
* @param methodName
* @param method
*/
public void addMethodMap(String methodName, Method method) {
methodMap.put(methodName, method);
}
public boolean supportMethod(String msId) {
Class> mongoDaoClass = MsUtil.getMongoDaoClass(msId);
if (mongoDaoClass != null && this.mongoDaoClass.isAssignableFrom(mongoDaoClass)) {
String methodName = MsUtil.getMethodName(msId);
return methodMap.get(methodName) != null;
}
return false;
}
public Update buildUpdateSet(ExampleStr o) {
Update localUpdate = new Update();
Iterator> iterator = o.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
localUpdate.set(entry.getKey(), entry.getValue());
}
return localUpdate;
}
public Map getMethodMap() {
return methodMap;
}
protected void resetCommandSource(MongoDaoStatement ms, CommandSource commandSource) {
try {
ReflectionUtil.setProperty(ms, "commandSource", commandSource);
} catch (IllegalAccessException e) {
throw new MongoProviderException("reset commandSource failed !");
}
}
public void resetCommandSource(MongoDaoStatement ms) throws Exception {
if (this.mongoDaoClass == MsUtil.getMongoDaoClass(ms.getId())) {
throw new MongoDaoException("Please do not configure or scan the generic MongoDao interface class.:" + this.mongoDaoClass);
}
Method method = methodMap.get(MsUtil.getMethodName(ms));
try {
//first situation, process return void
if (method.getReturnType() == Void.TYPE) {
method.invoke(this, ms);
}
//second situation,,process return CommandSource
else if (CommandSource.class.isAssignableFrom(method.getReturnType())) {
CommandSource commandSource = (CommandSource) method.invoke(this, ms);
resetCommandSource(ms, commandSource);
}
//third situation,,process return CommandSource
else if (DynamicCommand.class.equals(method.getReturnType())) {
DynamicCommand dynamicCommand = (DynamicCommand) method.invoke(this, ms);
CommandSource commandSource = new DynamicCommandSource(ms.getConfiguration(), dynamicCommand);
resetCommandSource(ms, commandSource);
}
//fourth situation,,process return dynamic query string
else if (String.class.equals(method.getReturnType())) {
String query = (String) method.invoke(this, ms);
DynamicCommand dynamicCommand = new DynamicCommand(query);
CommandSource commandSource = new DynamicCommandSource(ms.getConfiguration(), dynamicCommand);
resetCommandSource(ms, commandSource);
} else {
throw new MongoDaoException("The custom MongoProvider method returns a type error. The optional return type is void, CommandSource, DynamicCommand, and String !");
}
} catch (IllegalAccessException e) {
throw new MongoDaoException(e);
} catch (InvocationTargetException e) {
throw new MongoDaoException(e.getTargetException() != null ? e.getTargetException() : e);
}
}
}