blob: f3666d25196da762e1d8ca87f250e381832e33dc [file] [log] [blame]
package org.apache.sling.mailarchiveserver.impl;
import static org.apache.sling.mailarchiveserver.impl.SearchQueryParserImpl.MESSAGE_FIELDS;
import static org.apache.sling.mailarchiveserver.impl.SearchQueryParserImpl.SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP;
import java.util.List;
import java.util.Map;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.mailarchiveserver.api.QueryBuilder;
import org.apache.sling.mailarchiveserver.impl.SearchQueryParserImpl.SearchParameter;
@Component
@Service(QueryBuilder.class)
public class QueryBuilderImpl implements QueryBuilder {
static final String BASE = "SELECT * FROM [nt:unstructured] WHERE [sling:resourceType] = 'mailarchiveserver/message'";
static final String DUMMY = "SELECT * FROM [nt:frozenNode] WHERE [42] = 0";
private static final String AND = " AND ";
private static final String OR = " OR ";
public static final String SQL2 = "SQL2";
private String buildSQL2Query(Map<String, List<String>> tokens) {
if (tokens == null) {
return BASE;
} else if (tokens.size() == 0) {
return DUMMY;
}
String constraints = "";
// tokens constraints
for (String tokenClass : tokens.keySet()) {
if (tokenClass.equals(SearchParameter.NONE)) {
continue;
}
String fieldConstraint = buildFieldConstraints(tokenClass, tokens);
constraints += "("+ fieldConstraint +")" + AND;
}
// global constraints
String globalConstraint = "";
List<String> ls = tokens.get(SearchParameter.NONE);
if (ls != null) {
for (String msgField : MESSAGE_FIELDS) {
for (String value : ls) {
if (!value.trim().equals("")) {
globalConstraint += sqlLikeConstraint(sqlLower(msgField), value.toLowerCase()) + OR;
}
}
}
globalConstraint = globalConstraint.substring(0, globalConstraint.length()-OR.length());
}
if (!globalConstraint.equals("")) {
constraints += "("+ globalConstraint +")" + AND;
}
if (constraints.equals("")) {
return BASE;
} else {
return BASE + " AND " + constraints.substring(0, constraints.length()-AND.length());
}
}
private static String buildFieldConstraints(String tokenClass, Map<String, List<String>> tokens) {
List<String> ls = tokens.get(tokenClass);
String messageField = SEARCH_PARAMETER_TO_MESSAGE_FIELD_MAP.get(tokenClass);
String fieldConstraint = "";
for (String value : ls) {
if (!value.trim().equals("")) {
fieldConstraint += sqlLikeConstraint(sqlLower(messageField), value.toLowerCase()) + OR;
}
}
return fieldConstraint.substring(0, fieldConstraint.length()-OR.length());
}
private static String sqlLikeConstraint(String messageField, String value) {
return messageField + " LIKE '%" + value + "%'";
}
private static String sqlLower(String messageField) {
return "LOWER("+ messageField + ")";
}
@Override
public String buildQuery(Map<String, List<String>> tokens, String lang) {
if (lang.trim().equalsIgnoreCase(SQL2)) {
return buildSQL2Query(tokens);
} else {
throw new IllegalArgumentException("Invalid lang argument!");
}
}
}