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