package com.ctp.cdi.query.meta;
import static com.ctp.cdi.query.util.QueryUtils.isNotEmpty;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import com.ctp.cdi.query.Query;
import com.ctp.cdi.query.builder.MethodExpressionException;
import com.ctp.cdi.query.builder.part.QueryRoot;
import com.ctp.cdi.query.builder.result.QueryProcessor;
import com.ctp.cdi.query.builder.result.QueryProcessorFactory;
/**
* Stores information about a specific method of a DAO:
* <ul>
* <li>The reference to the Method reflection object</li>
* <li>Whether this method delegates, is annotated or is parsed</li>
* <li>A reference to the parent DAO</li>
* <li>For parsed DAO methods, also the JPQL string is cached</li>
* </ul>
*
* @author thomashug
*/
public class DaoMethod {
private final Method method;
private final MethodType methodType;
private final DaoComponent dao;
private final QueryRoot queryRoot;
private final QueryProcessor queryProcessor;
public DaoMethod(Method method, DaoComponent dao) {
this.method = method;
this.dao = dao;
this.methodType = extractMethodType();
this.queryRoot = initQueryRoot();
this.queryProcessor = QueryProcessorFactory.newInstance(method).build();
}
public boolean returns(Class<?> returnType) {
return returnType.equals(method.getReturnType());
}
private MethodType extractMethodType() {
if (isAnnotated()) {
return MethodType.ANNOTATED;
}
if (isMethodExpression()) {
return MethodType.PARSE;
}
return MethodType.DELEGATE;
}
private QueryRoot initQueryRoot() {
if (methodType == MethodType.PARSE) {
return QueryRoot.create(method.getName(), dao);
}
return QueryRoot.UNKNOWN_ROOT;
}
private boolean isAnnotated() {
if (method.isAnnotationPresent(Query.class)) {
Query query = method.getAnnotation(Query.class);
return isValid(query);
}
return false;
}
private boolean isValid(Query query) {
return isNotEmpty(query.value()) || isNotEmpty(query.named()) || isNotEmpty(query.sql());
}
private boolean isMethodExpression() {
if (!Modifier.isAbstract(method.getModifiers())) {
return false;
}
try {
QueryRoot.create(method.getName(), dao);
return true;
} catch (MethodExpressionException e) {
return false;
}
}
public MethodType getMethodType() {
return methodType;
}
public DaoComponent getDao() {
return dao;
}
public QueryRoot getQueryRoot() {
return queryRoot;
}
public QueryProcessor getQueryProcessor() {
return queryProcessor;
}
}