001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.search;
016    
017    import com.liferay.portal.kernel.util.StringPool;
018    import com.liferay.portal.kernel.util.StringUtil;
019    import com.liferay.portal.kernel.util.Validator;
020    
021    import java.util.ArrayList;
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.regex.Pattern;
026    
027    /**
028     * @author Brian Wing Shun Chan
029     * @author Hugo Huijser
030     */
031    public abstract class BaseBooleanQueryImpl
032            extends BaseQueryImpl implements BooleanQuery {
033    
034            public void addTerms(String[] fields, String values) throws ParseException {
035                    if (Validator.isNull(values)) {
036                            return;
037                    }
038    
039                    if (fields == null) {
040                            fields = new String[0];
041                    }
042    
043                    for (String field : fields) {
044                            addTerm(field, values);
045                    }
046            }
047    
048            public void addTerms(String[] fields, String value, boolean like)
049                    throws ParseException {
050    
051                    if (Validator.isNull(value)) {
052                            return;
053                    }
054    
055                    for (String field : fields) {
056                            addTerm(field, value, like);
057                    }
058            }
059    
060            protected void addTerms(
061                            String[] fields, Map<String, List<String>> termFieldsValuesMap)
062                    throws ParseException {
063    
064                    for (String field : fields) {
065                            List<String> valuesList = termFieldsValuesMap.get(field);
066    
067                            for (String value : valuesList) {
068                                    addTerm(field, value);
069                            }
070                    }
071            }
072    
073            protected String getTermFieldRemainderValues(
074                    String field, String values, List<String> valuesList, String pattern,
075                    String replacement) {
076    
077                    if (Validator.isNull(values)) {
078                            return values;
079                    }
080    
081                    if (Validator.isNull(pattern) || Validator.isNull(replacement)) {
082                            return values;
083                    }
084    
085                    if (Validator.isNotNull(field)) {
086                            field += ":";
087                    }
088                    else {
089                            field = StringPool.BLANK;
090                    }
091    
092                    while (values.matches(pattern)) {
093                            String value = values.replaceAll(pattern, replacement);
094    
095                            valuesList.add(value);
096    
097                            String duplicate =
098                                    "(?i)\\s*" + Pattern.quote(field + value) + "\\s*";
099    
100                            values = values.replaceAll(duplicate, StringPool.SPACE);
101                            values = values.trim();
102                    }
103    
104                    return values;
105            }
106    
107            protected Map<String, List<String>> getTermFieldsValuesMap(
108                    String[] fields, String values) {
109    
110                    Map<String, List<String>> termFieldsValuesMap =
111                            new HashMap<String, List<String>>();
112    
113                    for (String field : fields) {
114                            List<String> valuesList = new ArrayList<String>();
115    
116                            values = getTermFieldRemainderValues(
117                                    field, values, valuesList,
118                                    "(?i)^.*" + field + ":([\"\'])(.+?)(\\1).*$", "$1$2$3");
119    
120                            values = getTermFieldRemainderValues(
121                                    field, values, valuesList,
122                                    "(?i)^.*" + field + ":([^\\s\"']*).*$", "$1");
123    
124                            termFieldsValuesMap.put(field, valuesList);
125                    }
126    
127                    values = values.trim();
128    
129                    List<String> valuesList = new ArrayList<String>();
130    
131                    if (Validator.isNotNull(values)) {
132                            values = getTermFieldRemainderValues(
133                                    null, values, valuesList,
134                                    "^[^\"\']*([\"\'])(.+?)(\\1)[^\"\']*$", "$1$2$3");
135    
136                            valuesList.add(values);
137                    }
138    
139                    termFieldsValuesMap.put("no_field", valuesList);
140    
141                    return termFieldsValuesMap;
142            }
143    
144            protected String[] parseKeywords(String values) {
145                    if (!values.contains(StringPool.QUOTE)) {
146                            return StringUtil.split(values, StringPool.SPACE);
147                    }
148    
149                    List<String> keywords = new ArrayList<String>();
150    
151                    while (values.length() > 0) {
152                            if (values.startsWith(StringPool.QUOTE)) {
153                                    values = values.substring(1);
154    
155                                    if (values.contains(StringPool.QUOTE)) {
156                                            int pos = values.indexOf(StringPool.QUOTE);
157    
158                                            keywords.add(values.substring(0, pos));
159    
160                                            values = values.substring(pos + 1);
161                                            values = values.trim();
162                                    }
163                            }
164                            else {
165                                    if (values.contains(StringPool.SPACE)) {
166                                            int pos = values.indexOf(StringPool.SPACE);
167    
168                                            keywords.add(values.substring(0, pos));
169    
170                                            values = values.substring(pos + 1);
171                                            values = values.trim();
172                                    }
173                                    else {
174                                            keywords.add(values);
175    
176                                            break;
177                                    }
178                            }
179                    }
180    
181                    return keywords.toArray(new String[keywords.size()]);
182            }
183    
184    }