package play.modules.cream.ocm;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.jcr.RepositoryException;
import play.exceptions.UnexpectedException;
import play.modules.cream.helpers.JcrUtils;
public class JcrQuery {
public static class JcrQueryBuilder {
private final String query;
private final Class<?> clazz;
private Map<String, Object> params = new HashMap<String, Object>();
public JcrQueryBuilder(Class<?> clazz, String query) {
this.query = query;
this.clazz = clazz;
}
public JcrQuery build() {
return new JcrQuery(this);
}
public JcrQueryBuilder setBoolean(String name, boolean value) {
put(name, value);
return this;
}
public JcrQueryBuilder setDouble(String name, double value) {
put(name, value);
return this;
}
public JcrQueryBuilder setFloat(String name, float value) {
put(name, value);
return this;
}
public JcrQueryBuilder setInt(String name, int value) {
put(name, value);
return this;
}
public JcrQueryBuilder setLong(String name, long value) {
put(name, value);
return this;
}
public JcrQueryBuilder setNumber(String name, Number value) {
put(name, value);
return this;
}
public JcrQueryBuilder setObject(String name, Object value) {
put(name, value);
return this;
}
public JcrQueryBuilder setString(String name, String value) {
if (value != null) {
this.params.put(name, '\'' + JcrUtils.escapeSingleQuote(value) + '\'');
}
return this;
}
private void put(String name, Object value) {
if (value != null) {
params.put(name, value);
}
}
}
public static JcrQueryBuilder builder(Class<?> clazz, String query) {
return new JcrQueryBuilder(clazz, query);
}
public static JcrQueryBuilder builder(String query) {
return new JcrQueryBuilder(null, query);
}
private final String formattedQuery;
private final Class<?> clazz;
private JcrQuery(JcrQueryBuilder builder) {
this.formattedQuery = format(builder.query, builder.params);
this.clazz = builder.clazz;
}
@SuppressWarnings("unchecked")
public <T> JcrQueryResult<T> excute() {
try {
return (JcrQueryResult<T>) JcrMapper.executeQuery(clazz, this.formattedQuery);
} catch (RepositoryException e) {
throw new UnexpectedException(e);
}
}
public String format(String query, Map<String, Object> params) {
StringBuilder builder = new StringBuilder(query);
for (Entry<String, Object> entry : params.entrySet()) {
int start;
String pattern = String.format("${%s}", entry.getKey());
String value = entry.getValue().toString();
// Replace every occurence of ${key} with value
while ((start = builder.indexOf(pattern)) != -1) {
builder.replace(start, start + pattern.length(), value);
}
}
return builder.toString();
}
public String getQuery() {
return this.formattedQuery;
}
@Override
public String toString() {
return "JcrQuery [query=" + formattedQuery + ", clazz=" + clazz + "]";
}
}