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.lucene;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.search.ParseException;
020    import com.liferay.portal.kernel.search.Query;
021    import com.liferay.portal.kernel.search.QueryTranslator;
022    import com.liferay.portal.kernel.search.StringQueryImpl;
023    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
024    import com.liferay.portal.kernel.util.StringPool;
025    
026    import java.lang.reflect.Field;
027    
028    import org.apache.lucene.index.Term;
029    import org.apache.lucene.queryParser.QueryParser;
030    import org.apache.lucene.search.BooleanClause;
031    import org.apache.lucene.search.BooleanQuery;
032    import org.apache.lucene.search.TermQuery;
033    import org.apache.lucene.search.WildcardQuery;
034    
035    /**
036     * @author Brian Wing Shun Chan
037     */
038    @DoPrivileged
039    public class QueryTranslatorImpl implements QueryTranslator {
040    
041            @Override
042            public Object translate(Query query) throws ParseException {
043                    if (query instanceof BooleanQueryImpl) {
044                            return ((BooleanQueryImpl)query).getBooleanQuery();
045                    }
046                    else if (query instanceof LuceneQueryImpl) {
047                            return ((LuceneQueryImpl)query).getQuery();
048                    }
049                    else if (query instanceof StringQueryImpl) {
050                            QueryParser queryParser = new QueryParser(
051                                    LuceneHelperUtil.getVersion(), StringPool.BLANK,
052                                    LuceneHelperUtil.getAnalyzer());
053    
054                            try {
055                                    return queryParser.parse(query.toString());
056                            }
057                            catch (org.apache.lucene.queryParser.ParseException pe) {
058                                    throw new ParseException(pe);
059                            }
060                    }
061                    else if (query instanceof TermQueryImpl) {
062                            return ((TermQueryImpl)query).getTermQuery();
063                    }
064                    else if (query instanceof TermRangeQueryImpl) {
065                            return ((TermRangeQueryImpl)query).getTermRangeQuery();
066                    }
067                    else {
068                            return null;
069                    }
070            }
071    
072            @Override
073            public Object translateForSolr(Query query) {
074                    Object queryObject = query.getWrappedQuery();
075    
076                    if (queryObject instanceof org.apache.lucene.search.Query) {
077                            adjustQuery((org.apache.lucene.search.Query)queryObject);
078                    }
079    
080                    return query;
081            }
082    
083            protected void adjustQuery(org.apache.lucene.search.Query query) {
084                    if (query instanceof BooleanQuery) {
085                            BooleanQuery booleanQuery = (BooleanQuery)query;
086    
087                            for (BooleanClause booleanClause : booleanQuery.getClauses()) {
088                                    adjustQuery(booleanClause.getQuery());
089                            }
090                    }
091                    else if (query instanceof TermQuery) {
092                            TermQuery termQuery = (TermQuery)query;
093    
094                            Term term = termQuery.getTerm();
095    
096                            try {
097                                    String text = term.text();
098    
099                                    if (text.matches("^\\s*[^\"].*\\s+.*[^\"]\\s*$(?m)")) {
100                                            text = StringPool.QUOTE.concat(text).concat(
101                                                    StringPool.QUOTE);
102    
103                                            _textField.set(term, text);
104                                    }
105                            }
106                            catch (Exception e) {
107                                    _log.error(e, e);
108                            }
109                    }
110                    else if (query instanceof WildcardQuery) {
111                            WildcardQuery wildcardQuery = (WildcardQuery)query;
112    
113                            Term term = wildcardQuery.getTerm();
114    
115                            try {
116                                    String text = term.text();
117    
118                                    if (text.matches("^\\s*\\*.*(?m)")) {
119                                            text = text.replaceFirst("\\*", StringPool.BLANK);
120    
121                                            _textField.set(term, text);
122                                    }
123                            }
124                            catch (Exception e) {
125                                    _log.error(e, e);
126                            }
127                    }
128            }
129    
130            private static Log _log = LogFactoryUtil.getLog(QueryTranslatorImpl.class);
131    
132            private static Field _textField = null;
133    
134            static {
135                    try {
136                            _textField = Term.class.getDeclaredField("text");
137    
138                            _textField.setAccessible(true);
139                    }
140                    catch (Exception e) {
141                            _log.error(e, e);
142                    }
143            }
144    
145    }