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