| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| 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!"); |
| } |
| } |
| |
| } |