package com.bagri.core.query;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Represents (X-)Query containing query expressions and parameters.
*
* @author Denis Sukhoroslov
*
*/
public class QueryBuilder implements Cloneable {
private static final Logger logger = LoggerFactory.getLogger(QueryBuilder.class);
private Map<Integer, ExpressionContainer> containers = new HashMap<>();
/**
* default constructor
*/
public QueryBuilder() {
//
}
/**
*
* @param containers the collection of all expressions constructing query
*/
public QueryBuilder(Collection<ExpressionContainer> containers) {
setContainers(containers);
}
/**
* {@inheritDoc}
*/
@Override
public QueryBuilder clone() {
return new QueryBuilder(containers.values());
}
/**
* Adds new expression container to the internal containers map
*
* @param container the expression container
*/
public void addContainer(ExpressionContainer container) {
int clnId = container.getBuilder().getCollectionId();
addContainer(clnId, container);
}
/**
* Associates expression container with the collection identifier provided
*
* @param clnId the collection identifier
* @param container the expression container
*/
public void addContainer(int clnId, ExpressionContainer container) {
ExpressionContainer oldValue = containers.put(clnId, container);
// ??
}
/**
*
* @param clnId the collection identifier
* @return expression container for the specified collection identifier
*/
public ExpressionContainer getContainer(int clnId) {
return containers.get(clnId);
}
/**
*
* @return the internally stored expression containers
*/
public Collection<ExpressionContainer> getContainers() {
return containers.values();
}
/**
*
* @param containers the expression containers to store
*/
public void setContainers(Collection<ExpressionContainer> containers) {
this.containers.clear();
if (containers != null) {
for (ExpressionContainer ec: containers) {
addContainer(ec.clone());
}
}
}
/**
*
* @return all parameter names used in query expressions
*/
public Collection<String> getParamNames() {
List<String> result = new ArrayList<>();
for (ExpressionContainer exCont: containers.values()) {
for (Map.Entry<String, Object> param: exCont.getParams().entrySet()) {
result.add(param.getKey());
}
}
return result;
}
/**
*
* @return all parameter names which has no bound parameter value
*/
public Collection<String> getEmptyParams() {
List<String> result = new ArrayList<>();
for (ExpressionContainer exCont: containers.values()) {
for (Map.Entry<String, Object> param: exCont.getParams().entrySet()) {
if (param.getValue() == null) {
result.add(param.getKey());
}
}
}
return result;
}
/**
*
* @return true if query has any unbound parameter
*/
public boolean hasEmptyParams() {
for (ExpressionContainer exCont: containers.values()) {
for (Object value: exCont.getParams().values()) {
if (value == null) {
return true;
}
}
}
return false;
}
/**
* Bind parameter if it has no value yet
*
* @param pName th parameter name
* @param value the parameter value
*/
public void setEmptyParam(String pName, Object value) {
for (ExpressionContainer exCont: containers.values()) {
if (exCont.getParams().containsKey(pName) && exCont.getParam(pName) == null) {
exCont.getParams().put(pName, value);
}
}
}
/**
* reset parameters in all underlying query expressions
*
* @param params the parameters to use
*/
public void resetParams(Map<String, Object> params) {
logger.trace("resetParams; this: {}; got params: {}", this, params);
for (ExpressionContainer exCont: containers.values()) {
exCont.resetParams(params);
}
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return super.toString() + " [" + containers + "]";
}
}