package org.genedb.querying.core;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* A factory for returning queries, with the option of filtering them by name or by {@link NumericQueryVisibility}.
*
* @author art
* @author gv1
*
*/
public class QueryFactory<T extends QueryVisibility> {
private static Logger logger = Logger.getLogger(QueryFactory.class);
@Autowired
private ApplicationContext applicationContext;
private Map<T, List<QueryDetails>> visibilityQueryDetails;
private Map<String, T> nameVisibility;
public void setQueryNameMap(LinkedHashMap<T, Map<String, Query>> queryNameMap) {
this.visibilityQueryDetails = Maps.newHashMapWithExpectedSize(queryNameMap.size());
this.nameVisibility = Maps.newHashMap();
for (T visibility : queryNameMap.keySet()) {
List<QueryDetails> queryDetails = Lists.newArrayList();
visibilityQueryDetails.put(visibility, queryDetails);
for (Map.Entry<String, Query> entry : queryNameMap.get(visibility).entrySet()) {
String realName = entry.getKey();
Query q = entry.getValue();
QueryDetails qd = new QueryDetails(realName, q.getQueryName(), q.getQueryDescription());
queryDetails.add(qd);
nameVisibility.put(realName, visibility);
}
}
}
/**
* Retrieves a query with of a certain name.
*
* @param queryName
* @return a Query
* @throws IllegalAccessException
*/
public Query retrieveQuery(String queryName, T visibility) {
T v = nameVisibility.get(queryName);
if (v == null || !v.includesVisibility(visibility)) {
logger.error(String.format("Can't access query '%s' as it's visibility '%s' is below required '%s'", queryName, v, visibility));
return null;
}
return applicationContext.getBean(queryName, Query.class);
}
public String getRealName(Query query) {
for (Map.Entry<T, List<QueryDetails>> entry : visibilityQueryDetails.entrySet()) {
// entry.getValue().getRealName();
for (QueryDetails details : entry.getValue()) {
if (details.getQueryName().equals(query.getQueryName())) {
return details.getRealName();
}
}
}
return null;
}
/**
*
* Filters the available queries by visibility.
*
* @param visibility
* @return
*/
private List<QueryDetails> listQueries(T visibility) {
List<QueryDetails> ret = Lists.newArrayList();
for (Map.Entry<T, List<QueryDetails>> entry : visibilityQueryDetails.entrySet()) {
if (entry.getKey().includesVisibility(visibility)) {
ret.addAll(entry.getValue());
}
}
return ret;
}
/**
*
* Lists queries that are of equal or greater than visibility than the supplied visibility, filtered by name.
*
* @author gv1
*
* @param filterName
* @param visibility
* @return a map of queries
*/
public List<QueryDetails> listQueries(String filterName, T visibility) {
List<QueryDetails> visibleQueries = listQueries(visibility);
if (!StringUtils.hasLength(filterName)) {
return visibleQueries;
}
return filterByName(visibleQueries, filterName);
}
private List<QueryDetails> filterByName(List<QueryDetails> in, String filterName) {
List<QueryDetails> ret = Lists.newArrayList();
for (QueryDetails qd : in) {
if (qd.getRealName().contains(filterName)) {
ret.add(qd);
}
}
return ret;
}
}