001/** 002 * Copyright 2015 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package core.tut.pori.dao.filter; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.HashSet; 021import java.util.Iterator; 022import java.util.List; 023import java.util.Set; 024 025import org.apache.commons.lang3.StringUtils; 026import org.apache.solr.client.solrj.util.ClientUtils; 027 028import core.tut.pori.dao.SolrQueryBuilder; 029 030/** 031 * Basic and filter with OR relation to other query filters, the values themselves have OR relation with one another. 032 * 033 * Comparison to null (non-existent) value is accepted. 034 */ 035public class OrQueryFilter implements AbstractQueryFilter { 036 private static final char SOLR_NEGATIVE_QUERY = '-'; 037 private String _fieldName = null; 038 private Set<String> _values = null; 039 private boolean _hasNullValue = false; 040 041 /** 042 * 043 * @param fieldName 044 * @param values 045 * @throws IllegalArgumentException on bad field name 046 */ 047 public OrQueryFilter(String fieldName, Collection<? extends Object> values) throws IllegalArgumentException{ 048 addFilter(fieldName, values); 049 } 050 051 /** 052 * 053 * @param fieldName 054 * @param value 055 * @throws IllegalArgumentException on bad field name 056 */ 057 public OrQueryFilter(String fieldName, Object value) throws IllegalArgumentException{ 058 if(StringUtils.isBlank(fieldName)){ 059 throw new IllegalArgumentException("No field name."); 060 } 061 _fieldName = fieldName; 062 if(value == null){ 063 _hasNullValue = true; 064 }else{ 065 _values = new HashSet<>(1); 066 _values.add(ClientUtils.escapeQueryChars(String.valueOf(value))); 067 } 068 } 069 070 /** 071 * 072 * @param fieldName 073 * @param values 074 * @throws IllegalArgumentException on bad field name 075 */ 076 public OrQueryFilter(String fieldName, long[] values) throws IllegalArgumentException{ 077 List<String> v = null; 078 if(values != null){ 079 v = new ArrayList<>(values.length); 080 for(int i=0;i<values.length;++i){ 081 v.add(String.valueOf(values[i])); 082 } 083 } 084 addFilter(fieldName, v); 085 } 086 087 /** 088 * 089 * @param fieldName 090 * @param values 091 * @throws IllegalArgumentException on bad field name 092 */ 093 public OrQueryFilter(String fieldName, int[] values) throws IllegalArgumentException{ 094 List<String> v = null; 095 if(values != null){ 096 v = new ArrayList<>(values.length); 097 for(int i=0;i<values.length;++i){ 098 v.add(String.valueOf(values[i])); 099 } 100 } 101 addFilter(fieldName, v); 102 } 103 104 /** 105 * 106 * @param fieldName 107 * @param values 108 * @throws IllegalArgumentException on bad field name 109 */ 110 private void addFilter(String fieldName, Collection<? extends Object> values) throws IllegalArgumentException{ 111 if(StringUtils.isBlank(fieldName)){ 112 throw new IllegalArgumentException("No field name."); 113 } 114 115 _fieldName = fieldName; 116 if(values == null || values.isEmpty()){ 117 _hasNullValue = true; 118 return; 119 } 120 121 _values = new HashSet<>(values.size()); 122 for(Iterator<? extends Object> iter = values.iterator(); iter.hasNext();){ 123 Object value = iter.next(); 124 if(value == null){ 125 _hasNullValue = true; 126 }else{ 127 _values.add(ClientUtils.escapeQueryChars(String.valueOf(value))); 128 } 129 } 130 131 if(_values.isEmpty()){ // if there was only the null value 132 _values = null; 133 } 134 } 135 136 @Override 137 public void toFilterString(StringBuilder fq) { 138 fq.append('('); 139 if(_values != null){ 140 fq.append(_fieldName); 141 fq.append(SolrQueryBuilder.SEPARATOR_SOLR_FIELD_VALUE); 142 fq.append('('); 143 Iterator<String> iter = _values.iterator(); 144 fq.append(iter.next()); 145 while(iter.hasNext()){ 146 fq.append(SOLR_OR); 147 fq.append(iter.next()); 148 } 149 150 if(_hasNullValue){ 151 fq.append(") OR ("); 152 }else{ 153 fq.append(')'); 154 } 155 } 156 157 if(_hasNullValue){ 158 fq.append("("+SolrQueryBuilder.QUERY_ALL+SOLR_AND+" "+SOLR_NEGATIVE_QUERY); 159 fq.append(_fieldName); 160 fq.append(SolrQueryBuilder.SEPARATOR_SOLR_FIELD_VALUE+"["+SolrQueryBuilder.SOLR_WILD_CARD+" TO "+SolrQueryBuilder.SOLR_WILD_CARD+"])"); 161 } 162 163 fq.append(')'); 164 } 165 166 @Override 167 public QueryType getQueryType() { 168 return QueryType.OR; 169 } 170}