001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.search.filter;
016    
017    import com.liferay.portal.kernel.search.BooleanClause;
018    import com.liferay.portal.kernel.search.BooleanClauseOccur;
019    import com.liferay.portal.kernel.search.generic.BooleanClauseImpl;
020    import com.liferay.portal.kernel.util.SortedArrayList;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    
024    import java.util.Comparator;
025    import java.util.List;
026    
027    /**
028     * @author Michael C. Han
029     */
030    public class BooleanFilter extends BaseFilter {
031    
032            @Override
033            public <T> T accept(FilterVisitor<T> filterVisitor) {
034                    return filterVisitor.visit(this);
035            }
036    
037            public Filter add(Filter filter) {
038                    return add(filter, BooleanClauseOccur.SHOULD);
039            }
040    
041            public Filter add(Filter filter, BooleanClauseOccur booleanClauseOccur) {
042                    BooleanClause<Filter> booleanClause = new BooleanClauseImpl<>(
043                            filter, booleanClauseOccur);
044    
045                    if (booleanClauseOccur.equals(BooleanClauseOccur.MUST)) {
046                            _mustBooleanClauses.add(booleanClause);
047                    }
048                    else if (booleanClauseOccur.equals(BooleanClauseOccur.MUST_NOT)) {
049                            _mustNotBooleanClauses.add(booleanClause);
050                    }
051                    else {
052                            _shouldBooleanClauses.add(booleanClause);
053                    }
054    
055                    return filter;
056            }
057    
058            public Filter addRangeTerm(String field, int startValue, int endValue) {
059                    RangeTermFilter rangeTermFilter = new RangeTermFilter(
060                            field, true, true, String.valueOf(startValue),
061                            String.valueOf(endValue));
062    
063                    return add(rangeTermFilter, BooleanClauseOccur.SHOULD);
064            }
065    
066            public Filter addRangeTerm(
067                    String field, Integer startValue, Integer endValue) {
068    
069                    return addRangeTerm(field, startValue.intValue(), endValue.intValue());
070            }
071    
072            public Filter addRangeTerm(String field, long startValue, long endValue) {
073                    RangeTermFilter rangeTermFilter = new RangeTermFilter(
074                            field, true, true, String.valueOf(startValue),
075                            String.valueOf(endValue));
076    
077                    return add(rangeTermFilter, BooleanClauseOccur.SHOULD);
078            }
079    
080            public Filter addRangeTerm(String field, Long startValue, Long endValue) {
081                    return addRangeTerm(
082                            field, startValue.longValue(), endValue.longValue());
083            }
084    
085            public Filter addRangeTerm(String field, short startValue, short endValue) {
086                    RangeTermFilter rangeTermFilter = new RangeTermFilter(
087                            field, true, true, String.valueOf(startValue),
088                            String.valueOf(endValue));
089    
090                    return add(rangeTermFilter, BooleanClauseOccur.SHOULD);
091            }
092    
093            public Filter addRangeTerm(String field, Short startValue, Short endValue) {
094                    return addRangeTerm(
095                            field, startValue.shortValue(), endValue.shortValue());
096            }
097    
098            public Filter addRangeTerm(
099                    String field, String startValue, String endValue) {
100    
101                    RangeTermFilter rangeTermFilter = new RangeTermFilter(
102                            field, true, true, startValue, endValue);
103    
104                    return add(rangeTermFilter, BooleanClauseOccur.SHOULD);
105            }
106    
107            public Filter addRequiredTerm(String field, boolean value) {
108                    return addRequiredTerm(field, String.valueOf(value));
109            }
110    
111            public Filter addRequiredTerm(String field, Boolean value) {
112                    return addRequiredTerm(field, String.valueOf(value));
113            }
114    
115            public Filter addRequiredTerm(String field, double value) {
116                    return addRequiredTerm(field, String.valueOf(value));
117            }
118    
119            public Filter addRequiredTerm(String field, Double value) {
120                    return addRequiredTerm(field, String.valueOf(value));
121            }
122    
123            public Filter addRequiredTerm(String field, int value) {
124                    return addRequiredTerm(field, String.valueOf(value));
125            }
126    
127            public Filter addRequiredTerm(String field, Integer value) {
128                    return addRequiredTerm(field, String.valueOf(value));
129            }
130    
131            public Filter addRequiredTerm(String field, long value) {
132                    return addRequiredTerm(field, String.valueOf(value));
133            }
134    
135            public Filter addRequiredTerm(String field, Long value) {
136                    return addRequiredTerm(field, String.valueOf(value));
137            }
138    
139            public Filter addRequiredTerm(String field, short value) {
140                    return addRequiredTerm(field, String.valueOf(value));
141            }
142    
143            public Filter addRequiredTerm(String field, Short value) {
144                    return addRequiredTerm(field, String.valueOf(value));
145            }
146    
147            public Filter addRequiredTerm(String field, String value) {
148                    TermFilter termFilter = new TermFilter(field, value);
149    
150                    return add(termFilter, BooleanClauseOccur.MUST);
151            }
152    
153            public Filter addTerm(String field, boolean value) {
154                    return addTerm(field, String.valueOf(value));
155            }
156    
157            public Filter addTerm(String field, Boolean value) {
158                    return addTerm(field, String.valueOf(value));
159            }
160    
161            public Filter addTerm(String field, double value) {
162                    return addTerm(field, String.valueOf(value));
163            }
164    
165            public Filter addTerm(String field, Double value) {
166                    return addTerm(field, String.valueOf(value));
167            }
168    
169            public Filter addTerm(String field, int value) {
170                    return addTerm(field, String.valueOf(value));
171            }
172    
173            public Filter addTerm(String field, Integer value) {
174                    return addTerm(field, String.valueOf(value));
175            }
176    
177            public Filter addTerm(String field, long value) {
178                    return addTerm(field, String.valueOf(value));
179            }
180    
181            public Filter addTerm(String field, Long value) {
182                    return addTerm(field, String.valueOf(value));
183            }
184    
185            public Filter addTerm(String field, short value) {
186                    return addTerm(field, String.valueOf(value));
187            }
188    
189            public Filter addTerm(String field, Short value) {
190                    return addTerm(field, String.valueOf(value));
191            }
192    
193            public Filter addTerm(String field, String value) {
194                    return addTerm(field, value, BooleanClauseOccur.SHOULD);
195            }
196    
197            public Filter addTerm(
198                    String field, String value, BooleanClauseOccur booleanClauseOccur) {
199    
200                    TermFilter termFilter = new TermFilter(field, value);
201    
202                    return add(termFilter, booleanClauseOccur);
203            }
204    
205            public List<BooleanClause<Filter>> getMustBooleanClauses() {
206                    return _mustBooleanClauses;
207            }
208    
209            public List<BooleanClause<Filter>> getMustNotBooleanClauses() {
210                    return _mustNotBooleanClauses;
211            }
212    
213            public List<BooleanClause<Filter>> getShouldBooleanClauses() {
214                    return _shouldBooleanClauses;
215            }
216    
217            @Override
218            public int getSortOrder() {
219                    return 10;
220            }
221    
222            public boolean hasClauses() {
223                    if (!_mustBooleanClauses.isEmpty() ||
224                            !_mustNotBooleanClauses.isEmpty() ||
225                            !_shouldBooleanClauses.isEmpty()) {
226    
227                            return true;
228                    }
229    
230                    return false;
231            }
232    
233            @Override
234            public String toString() {
235                    StringBundler sb = new StringBundler(9);
236    
237                    sb.append("{MUST(");
238                    sb.append(getBooleanClauseString(_mustBooleanClauses));
239                    sb.append("), MUST_NOT(");
240                    sb.append(getBooleanClauseString(_mustNotBooleanClauses));
241                    sb.append("), SHOULD(");
242                    sb.append(getBooleanClauseString(_shouldBooleanClauses));
243                    sb.append("), ");
244                    sb.append(super.toString());
245                    sb.append("}");
246    
247                    return sb.toString();
248            }
249    
250            protected String getBooleanClauseString(
251                    List<BooleanClause<Filter>> booleanClauses) {
252    
253                    StringBundler sb = new StringBundler(2 * booleanClauses.size());
254    
255                    for (BooleanClause<Filter> booleanClause : _mustBooleanClauses) {
256                            sb.append(booleanClause);
257    
258                            sb.append(StringPool.COMMA_AND_SPACE);
259                    }
260    
261                    return sb.toString();
262            }
263    
264            private final List<BooleanClause<Filter>> _mustBooleanClauses =
265                    new SortedArrayList<>(new BooleanClauseComparator());
266            private final List<BooleanClause<Filter>> _mustNotBooleanClauses =
267                    new SortedArrayList<>(new BooleanClauseComparator());
268            private final List<BooleanClause<Filter>> _shouldBooleanClauses =
269                    new SortedArrayList<>(new BooleanClauseComparator());
270    
271            private class BooleanClauseComparator
272                    implements Comparator<BooleanClause<Filter>> {
273    
274                    @Override
275                    public int compare(
276                            BooleanClause<Filter> booleanClause1,
277                            BooleanClause<Filter> booleanClause2) {
278    
279                            Filter filter1 = booleanClause1.getClause();
280                            Filter filter2 = booleanClause2.getClause();
281    
282                            if (filter1.getSortOrder() < filter2.getSortOrder()) {
283                                    return -1;
284                            }
285    
286                            if (filter1.getSortOrder() > filter2.getSortOrder()) {
287                                    return 1;
288                            }
289    
290                            return 0;
291                    }
292    
293            }
294    
295    }