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