package com.ctp.cdi.query.builder.result;
import java.lang.reflect.Method;
import java.util.List;
import javax.persistence.Query;
import com.ctp.cdi.query.Modifying;
import com.ctp.cdi.query.QueryResult;
public final class QueryProcessorFactory {
private final Method method;
private QueryProcessorFactory(Method method) {
this.method = method;
}
public static QueryProcessorFactory newInstance(Method method) {
return new QueryProcessorFactory(method);
}
public QueryProcessor build() {
if (returns(QueryResult.class)) {
return new NoOpQueryProcessor();
}
if (returns(List.class)) {
return new ListQueryProcessor();
}
if (isModifying()) {
return new ExecuteUpdateQueryProcessor(returns(Void.TYPE));
}
return new SingleResultQueryProcessor();
}
private boolean isModifying() {
boolean matchesType = Void.TYPE.equals(method.getReturnType()) ||
int.class.equals(method.getReturnType()) ||
Integer.class.equals(method.getReturnType());
return method.isAnnotationPresent(Modifying.class) && matchesType;
}
private boolean returns(Class<?> clazz) {
return method.getReturnType().isAssignableFrom(clazz);
}
private static final class ListQueryProcessor implements QueryProcessor {
@Override
public Object executeQuery(Query query) {
return query.getResultList();
}
}
private static final class NoOpQueryProcessor implements QueryProcessor {
@Override
public Object executeQuery(Query query) {
return query;
}
}
private static final class SingleResultQueryProcessor implements QueryProcessor {
@Override
public Object executeQuery(Query query) {
return query.getSingleResult();
}
}
private static final class ExecuteUpdateQueryProcessor implements QueryProcessor {
private final boolean returnsVoid;
private ExecuteUpdateQueryProcessor(boolean returnsVoid) {
this.returnsVoid = returnsVoid;
}
@Override
public Object executeQuery(Query query) {
int result = query.executeUpdate();
if (!returnsVoid) {
return result;
}
return null;
}
}
}