001
014
015 package com.liferay.portal.kernel.repository.cmis.search;
016
017 import com.liferay.portal.kernel.exception.SystemException;
018 import com.liferay.portal.kernel.search.BooleanClause;
019 import com.liferay.portal.kernel.search.BooleanClauseOccur;
020 import com.liferay.portal.kernel.search.BooleanQuery;
021 import com.liferay.portal.kernel.search.Field;
022 import com.liferay.portal.kernel.search.Query;
023 import com.liferay.portal.kernel.search.QueryConfig;
024 import com.liferay.portal.kernel.search.QueryTerm;
025 import com.liferay.portal.kernel.search.SearchContext;
026 import com.liferay.portal.kernel.search.SearchException;
027 import com.liferay.portal.kernel.search.Sort;
028 import com.liferay.portal.kernel.search.TermQuery;
029 import com.liferay.portal.kernel.search.TermRangeQuery;
030 import com.liferay.portal.kernel.search.WildcardQuery;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.StringBundler;
033 import com.liferay.portal.model.RepositoryEntry;
034 import com.liferay.portal.model.User;
035 import com.liferay.portal.service.RepositoryEntryLocalServiceUtil;
036 import com.liferay.portal.service.UserLocalServiceUtil;
037
038 import java.util.HashMap;
039 import java.util.HashSet;
040 import java.util.List;
041 import java.util.Map;
042 import java.util.Set;
043
044
047 public class BaseCmisSearchQueryBuilder implements CMISSearchQueryBuilder {
048
049 public String buildQuery(SearchContext searchContext, Query query)
050 throws SearchException {
051
052 StringBundler sb = new StringBundler();
053
054 sb.append("SELECT cmis:objectId");
055
056 QueryConfig queryConfig = searchContext.getQueryConfig();
057
058 if (queryConfig.isScoreEnabled()) {
059 sb.append(", SCORE() AS HITS");
060 }
061
062 sb.append(" FROM cmis:document");
063
064 CMISConjunction cmisConjunction = new CMISConjunction();
065
066 traverseQuery(cmisConjunction, query);
067
068 if (!cmisConjunction.isEmpty()) {
069 sb.append(" WHERE ");
070 sb.append(cmisConjunction.toQueryFragment());
071 }
072
073 Sort[] sorts = searchContext.getSorts();
074
075 if (queryConfig.isScoreEnabled() ||
076 ((sorts != null) && sorts.length > 0)) {
077
078 sb.append(" ORDER BY ");
079 }
080
081 if ((sorts != null) && (sorts.length > 0)) {
082 int i = 0;
083
084 for (Sort sort : sorts) {
085 String fieldName = sort.getFieldName();
086
087 if (!isSupportedField(fieldName)) {
088 continue;
089 }
090
091 if (i > 0) {
092 sb.append(", ");
093 }
094
095 sb.append(getCmisField(fieldName));
096
097 if (sort.isReverse()) {
098 sb.append(" DESC");
099 }
100 else {
101 sb.append(" ASC");
102 }
103
104 i++;
105 }
106 }
107 else if (queryConfig.isScoreEnabled()) {
108 sb.append("HITS DESC");
109 }
110
111 return sb.toString();
112 }
113
114 protected CMISCriterion buildFieldExpression(
115 String field, String value,
116 CMISSimpleExpressionOperator cmisSimpleExpressionOperator)
117 throws SearchException {
118
119 CMISCriterion cmisCriterion = null;
120
121 boolean wildcard =
122 CMISSimpleExpressionOperator.LIKE == cmisSimpleExpressionOperator;
123
124 if (field.equals(Field.CONTENT)) {
125 value = CMISParameterValueUtil.formatParameterValue(field, value);
126
127 cmisCriterion = new CMISContainsExpression(value);
128 }
129 else if (field.equals(Field.FOLDER_ID)) {
130 long folderId = GetterUtil.getLong(value);
131
132 try {
133 RepositoryEntry repositoryEntry =
134 RepositoryEntryLocalServiceUtil.fetchRepositoryEntry(
135 folderId);
136
137 if (repositoryEntry != null) {
138 String objectId = repositoryEntry.getMappedId();
139
140 objectId = CMISParameterValueUtil.formatParameterValue(
141 field, objectId, wildcard);
142
143 cmisCriterion = new CMISInFolderExpression(objectId);
144 }
145 }
146 catch (SystemException se) {
147 throw new SearchException(
148 "Unable to determine folder {folderId=" + folderId + "}",
149 se);
150 }
151 }
152 else if (field.equals(Field.USER_ID)) {
153 try {
154 long userId = GetterUtil.getLong(value);
155
156 User user = UserLocalServiceUtil.getUserById(userId);
157
158 String screenName = CMISParameterValueUtil.formatParameterValue(
159 field, user.getScreenName(), wildcard);
160
161 cmisCriterion = new CMISSimpleExpression(
162 getCmisField(field), screenName,
163 cmisSimpleExpressionOperator);
164 }
165 catch (Exception e) {
166 if (e instanceof SearchException) {
167 throw (SearchException)e;
168 }
169
170 throw new SearchException(
171 "Unable to determine user {" + field + "=" + value + "}",
172 e);
173 }
174 }
175 else {
176 value = CMISParameterValueUtil.formatParameterValue(
177 field, value, wildcard);
178
179 cmisCriterion = new CMISSimpleExpression(
180 getCmisField(field), value, cmisSimpleExpressionOperator);
181 }
182
183 return cmisCriterion;
184 }
185
186 protected String getCmisField(String field) {
187 return _cmisFields.get(field);
188 }
189
190 protected boolean isSupportedField(String field) {
191 return _supportedFields.contains(field);
192 }
193
194 protected void traverseQuery(CMISJunction criterion, Query query)
195 throws SearchException {
196
197 if (query instanceof BooleanQuery) {
198 BooleanQuery booleanQuery = (BooleanQuery)query;
199
200 List<BooleanClause> booleanClauses = booleanQuery.clauses();
201
202 CMISConjunction anyCMISConjunction = new CMISConjunction();
203 CMISConjunction notCMISConjunction = new CMISConjunction();
204 CMISDisjunction cmisDisjunction = new CMISDisjunction();
205
206 for (BooleanClause booleanClause : booleanClauses) {
207 CMISJunction cmisJunction = cmisDisjunction;
208
209 BooleanClauseOccur booleanClauseOccur =
210 booleanClause.getBooleanClauseOccur();
211
212 if (booleanClauseOccur.equals(BooleanClauseOccur.MUST)) {
213 cmisJunction = anyCMISConjunction;
214 }
215 else if (booleanClauseOccur.equals(
216 BooleanClauseOccur.MUST_NOT)) {
217
218 cmisJunction = notCMISConjunction;
219 }
220
221 Query booleanClauseQuery = booleanClause.getQuery();
222
223 traverseQuery(cmisJunction, booleanClauseQuery);
224 }
225
226 if (!anyCMISConjunction.isEmpty()) {
227 criterion.add(anyCMISConjunction);
228 }
229
230 if (!cmisDisjunction.isEmpty()) {
231 criterion.add(cmisDisjunction);
232 }
233
234 if (!notCMISConjunction.isEmpty()) {
235 criterion.add(new CMISNotExpression(notCMISConjunction));
236 }
237 }
238 else if (query instanceof TermQuery) {
239 TermQuery termQuery = (TermQuery)query;
240
241 QueryTerm queryTerm = termQuery.getQueryTerm();
242
243 if (!isSupportedField(queryTerm.getField())) {
244 return;
245 }
246
247 CMISCriterion cmisExpression = buildFieldExpression(
248 queryTerm.getField(), queryTerm.getValue(),
249 CMISSimpleExpressionOperator.EQ);
250
251 if (cmisExpression != null) {
252 criterion.add(cmisExpression);
253 }
254 }
255 else if (query instanceof TermRangeQuery) {
256 TermRangeQuery termRangeQuery = (TermRangeQuery)query;
257
258 if (!isSupportedField(termRangeQuery.getField())) {
259 return;
260 }
261
262 String fieldName = termRangeQuery.getField();
263
264 String cmisField = getCmisField(fieldName);
265 String cmisLowerTerm = CMISParameterValueUtil.formatParameterValue(
266 fieldName, termRangeQuery.getLowerTerm());
267 String cmisUpperTerm = CMISParameterValueUtil.formatParameterValue(
268 fieldName, termRangeQuery.getUpperTerm());
269
270 CMISCriterion cmisCriterion = new CMISBetweenExpression(
271 cmisField, cmisLowerTerm, cmisUpperTerm,
272 termRangeQuery.includesLower(), termRangeQuery.includesUpper());
273
274 criterion.add(cmisCriterion);
275 }
276 else if (query instanceof WildcardQuery) {
277 WildcardQuery wildcardQuery = (WildcardQuery)query;
278
279 QueryTerm queryTerm = wildcardQuery.getQueryTerm();
280
281 if (!isSupportedField(queryTerm.getField())) {
282 return;
283 }
284
285 CMISCriterion cmisCriterion = buildFieldExpression(
286 queryTerm.getField(), queryTerm.getValue(),
287 CMISSimpleExpressionOperator.LIKE);
288
289 if (cmisCriterion != null) {
290 criterion.add(cmisCriterion);
291 }
292 }
293 }
294
295 private static Map<String, String> _cmisFields;
296 private static Set<String> _supportedFields;
297
298 static {
299 _cmisFields = new HashMap<String, String>();
300
301 _cmisFields.put(Field.CREATE_DATE, "cmis:creationDate");
302 _cmisFields.put(Field.MODIFIED_DATE, "cmis:lastModificationDate");
303 _cmisFields.put(Field.NAME, "cmis:name");
304 _cmisFields.put(Field.TITLE, "cmis:name");
305 _cmisFields.put(Field.USER_ID, "cmis:createdBy");
306 _cmisFields.put(Field.USER_NAME, "cmis:createdBy");
307
308 _supportedFields = new HashSet<String>();
309
310 _supportedFields.add(Field.CREATE_DATE);
311 _supportedFields.add(Field.FOLDER_ID);
312 _supportedFields.add(Field.MODIFIED_DATE);
313 _supportedFields.add(Field.NAME);
314 _supportedFields.add(Field.TITLE);
315 _supportedFields.add(Field.USER_ID);
316 _supportedFields.add(Field.USER_NAME);
317 }
318
319 }