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.generic;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.search.BaseBooleanQueryImpl;
020    import com.liferay.portal.kernel.search.BooleanClause;
021    import com.liferay.portal.kernel.search.BooleanClauseOccur;
022    import com.liferay.portal.kernel.search.BooleanClauseOccurImpl;
023    import com.liferay.portal.kernel.search.BooleanQuery;
024    import com.liferay.portal.kernel.search.ParseException;
025    import com.liferay.portal.kernel.search.Query;
026    import com.liferay.portal.kernel.search.QueryTerm;
027    import com.liferay.portal.kernel.search.TermRangeQuery;
028    import com.liferay.portal.kernel.search.query.QueryVisitor;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.StringUtil;
031    
032    import java.util.ArrayList;
033    import java.util.Collection;
034    import java.util.Collections;
035    import java.util.List;
036    
037    /**
038     * @author Michael C. Han
039     * @author Hugo Huijser
040     */
041    public class BooleanQueryImpl extends BaseBooleanQueryImpl {
042    
043            @Override
044            public <T> T accept(QueryVisitor<T> queryVisitor) {
045                    return queryVisitor.visitQuery(this);
046            }
047    
048            @Override
049            public Query add(Query query, BooleanClauseOccur booleanClauseOccur) {
050                    _booleanClauses.add(new BooleanClauseImpl<>(query, booleanClauseOccur));
051    
052                    return query;
053            }
054    
055            @Override
056            public Query add(Query query, String occur) {
057                    BooleanClauseOccur booleanClauseOccur = new BooleanClauseOccurImpl(
058                            occur);
059    
060                    add(query, booleanClauseOccur);
061    
062                    return query;
063            }
064    
065            @Override
066            public Query addExactTerm(String field, boolean value) {
067                    return addExactTerm(field, String.valueOf(value));
068            }
069    
070            @Override
071            public Query addExactTerm(String field, Boolean value) {
072                    return addExactTerm(field, String.valueOf(value));
073            }
074    
075            @Override
076            public Query addExactTerm(String field, double value) {
077                    return addExactTerm(field, String.valueOf(value));
078            }
079    
080            @Override
081            public Query addExactTerm(String field, Double value) {
082                    return addExactTerm(field, String.valueOf(value));
083            }
084    
085            @Override
086            public Query addExactTerm(String field, int value) {
087                    return addExactTerm(field, String.valueOf(value));
088            }
089    
090            @Override
091            public Query addExactTerm(String field, Integer value) {
092                    return addExactTerm(field, String.valueOf(value));
093            }
094    
095            @Override
096            public Query addExactTerm(String field, long value) {
097                    return addExactTerm(field, String.valueOf(value));
098            }
099    
100            @Override
101            public Query addExactTerm(String field, Long value) {
102                    return addExactTerm(field, String.valueOf(value));
103            }
104    
105            @Override
106            public Query addExactTerm(String field, short value) {
107                    return addExactTerm(field, String.valueOf(value));
108            }
109    
110            @Override
111            public Query addExactTerm(String field, Short value) {
112                    return addExactTerm(field, String.valueOf(value));
113            }
114    
115            @Override
116            public Query addExactTerm(String field, String value) {
117                    TermQueryImpl termQuery = new TermQueryImpl(
118                            new QueryTermImpl(field, String.valueOf(value)));
119    
120                    return add(termQuery, BooleanClauseOccur.SHOULD);
121            }
122    
123            @Override
124            public Collection<Query> addNumericRangeTerm(
125                    String field, int startValue, int endValue) {
126    
127                    List<Query> queries = new ArrayList<>();
128    
129                    for (int i = startValue; i <= endValue; i++) {
130                            Query query = addExactTerm(field, i);
131    
132                            queries.add(query);
133                    }
134    
135                    return queries;
136            }
137    
138            @Override
139            public Collection<Query> addNumericRangeTerm(
140                    String field, Integer startValue, Integer endValue) {
141    
142                    return addNumericRangeTerm(
143                            field, startValue.intValue(), endValue.intValue());
144            }
145    
146            @Override
147            public Collection<Query> addNumericRangeTerm(
148                    String field, long startValue, long endValue) {
149    
150                    List<Query> queries = new ArrayList<>();
151    
152                    for (long i = startValue; i <= endValue; i++) {
153                            Query query = addExactTerm(field, i);
154    
155                            queries.add(query);
156                    }
157    
158                    return queries;
159            }
160    
161            @Override
162            public Collection<Query> addNumericRangeTerm(
163                    String field, Long startValue, Long endValue) {
164    
165                    return addNumericRangeTerm(
166                            field, startValue.longValue(), endValue.longValue());
167            }
168    
169            @Override
170            public Collection<Query> addNumericRangeTerm(
171                    String field, short startValue, short endValue) {
172    
173                    List<Query> queries = new ArrayList<>();
174    
175                    for (short i = startValue; i <= endValue; i++) {
176                            Query query = addExactTerm(field, i);
177    
178                            queries.add(query);
179                    }
180    
181                    return queries;
182            }
183    
184            @Override
185            public Collection<Query> addNumericRangeTerm(
186                    String field, Short startValue, Short endValue) {
187    
188                    return addNumericRangeTerm(
189                            field, startValue.shortValue(), endValue.shortValue());
190            }
191    
192            @Override
193            public Query addRangeTerm(String field, int startValue, int endValue) {
194                    TermRangeQuery termRangeQuery = new TermRangeQueryImpl(
195                            field, String.valueOf(startValue), String.valueOf(endValue), true,
196                            true);
197    
198                    return add(termRangeQuery, BooleanClauseOccur.SHOULD);
199            }
200    
201            @Override
202            public Query addRangeTerm(
203                    String field, Integer startValue, Integer endValue) {
204    
205                    return addRangeTerm(field, startValue.intValue(), endValue.intValue());
206            }
207    
208            @Override
209            public Query addRangeTerm(String field, long startValue, long endValue) {
210                    TermRangeQuery termRangeQuery = new TermRangeQueryImpl(
211                            field, String.valueOf(startValue), String.valueOf(endValue), true,
212                            true);
213    
214                    return add(termRangeQuery, BooleanClauseOccur.SHOULD);
215            }
216    
217            @Override
218            public Query addRangeTerm(String field, Long startValue, Long endValue) {
219                    return addRangeTerm(
220                            field, startValue.longValue(), endValue.longValue());
221            }
222    
223            @Override
224            public Query addRangeTerm(String field, short startValue, short endValue) {
225                    TermRangeQuery termRangeQuery = new TermRangeQueryImpl(
226                            field, String.valueOf(startValue), String.valueOf(endValue), true,
227                            true);
228    
229                    return add(termRangeQuery, BooleanClauseOccur.SHOULD);
230            }
231    
232            @Override
233            public Query addRangeTerm(String field, Short startValue, Short endValue) {
234                    return addRangeTerm(
235                            field, startValue.shortValue(), endValue.shortValue());
236            }
237    
238            @Override
239            public Query addRangeTerm(
240                    String field, String startValue, String endValue) {
241    
242                    TermRangeQuery termRangeQuery = new TermRangeQueryImpl(
243                            field, startValue, endValue, true, true);
244    
245                    return add(termRangeQuery, BooleanClauseOccur.SHOULD);
246            }
247    
248            @Override
249            public Query addRequiredTerm(String field, boolean value) {
250                    return addRequiredTerm(field, String.valueOf(value), false);
251            }
252    
253            @Override
254            public Query addRequiredTerm(String field, Boolean value) {
255                    return addRequiredTerm(field, String.valueOf(value), false);
256            }
257    
258            @Override
259            public Query addRequiredTerm(String field, double value) {
260                    return addRequiredTerm(field, String.valueOf(value), false);
261            }
262    
263            @Override
264            public Query addRequiredTerm(String field, Double value) {
265                    return addRequiredTerm(field, String.valueOf(value), false);
266            }
267    
268            @Override
269            public Query addRequiredTerm(String field, int value) {
270                    return addRequiredTerm(field, String.valueOf(value), false);
271            }
272    
273            @Override
274            public Query addRequiredTerm(String field, Integer value) {
275                    return addRequiredTerm(field, String.valueOf(value), false);
276            }
277    
278            @Override
279            public Query addRequiredTerm(String field, long value) {
280                    return addRequiredTerm(field, String.valueOf(value), false);
281            }
282    
283            @Override
284            public Query addRequiredTerm(String field, Long value) {
285                    return addRequiredTerm(field, String.valueOf(value), false);
286            }
287    
288            @Override
289            public Query addRequiredTerm(String field, short value) {
290                    return addRequiredTerm(field, String.valueOf(value), false);
291            }
292    
293            @Override
294            public Query addRequiredTerm(String field, Short value) {
295                    return addRequiredTerm(field, String.valueOf(value), false);
296            }
297    
298            @Override
299            public Query addRequiredTerm(String field, String value) {
300                    return addRequiredTerm(field, value, false);
301            }
302    
303            @Override
304            public Query addRequiredTerm(String field, String value, boolean like) {
305                    return addRequiredTerm(field, value, like, false);
306            }
307    
308            public Query addRequiredTerm(
309                    String field, String value, boolean like, boolean parseKeywords) {
310    
311                    if (like) {
312                            value = StringUtil.replace(
313                                    value, StringPool.PERCENT, StringPool.BLANK);
314                    }
315    
316                    String[] values = null;
317    
318                    if (parseKeywords) {
319                            values = parseKeywords(value);
320                    }
321                    else {
322                            values = new String[] {value};
323                    }
324    
325                    BooleanQuery booleanQuery = new BooleanQueryImpl();
326    
327                    for (String curValue : values) {
328                            QueryTerm queryTerm = new QueryTermImpl(
329                                    field, String.valueOf(curValue));
330    
331                            Query query = null;
332    
333                            if (like) {
334                                    query = new WildcardQueryImpl(queryTerm);
335                            }
336                            else {
337                                    query = new TermQueryImpl(queryTerm);
338                            }
339    
340                            try {
341                                    booleanQuery.add(query, BooleanClauseOccur.SHOULD);
342                            }
343                            catch (ParseException pe) {
344                                    if (_log.isDebugEnabled()) {
345                                            _log.debug("ParseException thrown, skipping query", pe);
346                                    }
347                            }
348                    }
349    
350                    return add(booleanQuery, BooleanClauseOccur.MUST);
351            }
352    
353            @Override
354            public Query addTerm(String field, long value) {
355                    return addTerm(field, String.valueOf(value), false);
356            }
357    
358            @Override
359            public Query addTerm(String field, String value) {
360                    return addTerm(field, value, false);
361            }
362    
363            @Override
364            public Query addTerm(String field, String value, boolean like) {
365                    return addTerm(field, value, like, BooleanClauseOccur.SHOULD);
366            }
367    
368            public Collection<Query> addTerm(
369                    String field, String value, boolean like, boolean parseKeywords) {
370    
371                    List<Query> queries = new ArrayList<>();
372    
373                    if (like) {
374                            value = StringUtil.replace(
375                                    value, StringPool.PERCENT, StringPool.BLANK);
376                    }
377    
378                    if (parseKeywords) {
379                            String[] keywords = parseKeywords(value);
380    
381                            for (String keyword : keywords) {
382                                    Query query = addTerm(field, keyword, like);
383    
384                                    queries.add(query);
385                            }
386                    }
387                    else {
388                            Query query = addTerm(field, value, like);
389    
390                            queries.add(query);
391                    }
392    
393                    return queries;
394            }
395    
396            @Override
397            public Query addTerm(
398                    String field, String value, boolean like,
399                    BooleanClauseOccur booleanClauseOccur) {
400    
401                    Query query = null;
402    
403                    if (like) {
404                            query = new WildcardQueryImpl(
405                                    new QueryTermImpl(field, String.valueOf(value)));
406                    }
407                    else {
408                            query = new TermQueryImpl(
409                                    new QueryTermImpl(field, String.valueOf(value)));
410                    }
411    
412                    return add(query, booleanClauseOccur);
413            }
414    
415            @Override
416            public List<BooleanClause<Query>> clauses() {
417                    return Collections.unmodifiableList(_booleanClauses);
418            }
419    
420            @Override
421            public boolean hasChildren() {
422                    return hasClauses();
423            }
424    
425            @Override
426            public boolean hasClauses() {
427                    return !_booleanClauses.isEmpty();
428            }
429    
430            private static final Log _log = LogFactoryUtil.getLog(
431                    BooleanQueryImpl.class);
432    
433            private final List<BooleanClause<Query>> _booleanClauses =
434                    new ArrayList<>();
435    
436    }