001
014
015 package com.liferay.portal.search.test;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.search.Hits;
019 import com.liferay.portal.kernel.search.SearchContext;
020 import com.liferay.portal.kernel.test.IdempotentRetryAssert;
021 import com.liferay.portal.kernel.test.util.SearchContextTestUtil;
022 import com.liferay.portal.kernel.test.util.ServiceContextTestUtil;
023 import com.liferay.portal.kernel.util.CharPool;
024 import com.liferay.portal.kernel.util.ListUtil;
025 import com.liferay.portal.kernel.util.LocaleUtil;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.StringUtil;
028 import com.liferay.portal.model.BaseModel;
029 import com.liferay.portal.model.Group;
030 import com.liferay.portal.service.ServiceContext;
031 import com.liferay.portlet.asset.AssetRendererFactoryRegistryUtil;
032 import com.liferay.portlet.asset.model.AssetEntry;
033 import com.liferay.portlet.asset.model.AssetRenderer;
034 import com.liferay.portlet.asset.model.AssetRendererFactory;
035 import com.liferay.portlet.asset.model.DDMFormValuesReader;
036 import com.liferay.portlet.asset.service.persistence.AssetEntryQuery;
037 import com.liferay.portlet.asset.service.persistence.test.AssetEntryQueryTestUtil;
038 import com.liferay.portlet.asset.util.AssetUtil;
039 import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
040 import com.liferay.portlet.dynamicdatamapping.model.DDMFormField;
041 import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldOptions;
042 import com.liferay.portlet.dynamicdatamapping.model.DDMFormFieldType;
043 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
044 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
045 import com.liferay.portlet.dynamicdatamapping.model.Value;
046 import com.liferay.portlet.dynamicdatamapping.render.ValueAccessor;
047 import com.liferay.portlet.dynamicdatamapping.storage.DDMFormFieldValue;
048 import com.liferay.portlet.dynamicdatamapping.storage.DDMFormValues;
049 import com.liferay.portlet.dynamicdatamapping.storage.FieldConstants;
050 import com.liferay.portlet.dynamicdatamapping.util.DDMIndexerUtil;
051 import com.liferay.portlet.dynamicdatamapping.util.test.DDMStructureTestUtil;
052 import com.liferay.portlet.dynamicdatamapping.util.test.DDMTemplateTestUtil;
053
054 import java.util.List;
055 import java.util.Locale;
056 import java.util.Map;
057 import java.util.concurrent.Callable;
058 import java.util.concurrent.TimeUnit;
059
060 import org.apache.commons.lang.ArrayUtils;
061
062 import org.junit.Assert;
063
064
068 public abstract class TestOrderHelper {
069
070 public void testOrderByDDMBooleanField() throws Exception {
071 testOrderByDDMField(
072 new String[] {"false", "true", "false", "true"},
073 new String[] {"false", "false", "true", "true"},
074 FieldConstants.BOOLEAN, DDMFormFieldType.CHECKBOX);
075 }
076
077 public void testOrderByDDMBooleanFieldRepeatable() throws Exception {
078 testOrderByDDMFieldRepeatable(
079 new String[] {
080 "true|true", "false|false", "true|true", "false|false"
081 },
082 new String[] {
083 "false|false", "false|false", "true|true", "true|true"
084 },
085 FieldConstants.BOOLEAN, DDMFormFieldType.CHECKBOX);
086 }
087
088 public void testOrderByDDMIntegerField() throws Exception {
089 testOrderByDDMField(
090 new String[] {"1", "10", "3", "2"},
091 new String[] {"1", "2", "3", "10"}, FieldConstants.INTEGER,
092 DDMFormFieldType.INTEGER);
093 }
094
095 public void testOrderByDDMIntegerFieldRepeatable() throws Exception {
096 testOrderByDDMFieldRepeatable(
097 new String[] {"50", "707|25", "1|99|42"},
098 new String[] {"1|99|42", "707|25", "50"}, FieldConstants.INTEGER,
099 DDMFormFieldType.INTEGER);
100 }
101
102 public void testOrderByDDMNumberField() throws Exception {
103 testOrderByDDMField(
104 new String[] {"3", "3.14", "12.34", "2.72", "1.41", "23.45", "20"},
105 new String[] {"1.41", "2.72", "3", "3.14", "12.34", "20", "23.45"},
106 FieldConstants.NUMBER, DDMFormFieldType.NUMBER);
107 }
108
109 public void testOrderByDDMNumberFieldRepeatable() throws Exception {
110 testOrderByDDMFieldRepeatable(
111 new String[] {"20|12.34", "16.0", "3.14"},
112 new String[] {"3.14", "20|12.34", "16.0"}, FieldConstants.NUMBER,
113 DDMFormFieldType.NUMBER);
114 }
115
116 public void testOrderByDDMRadioField() throws Exception {
117 testOrderByDDMRadioField("text");
118 }
119
120 public void testOrderByDDMRadioFieldKeyword() throws Exception {
121 testOrderByDDMRadioField("keyword");
122 }
123
124 public void testOrderByDDMTextField() throws Exception {
125 testOrderByDDMTextField("text");
126 }
127
128 public void testOrderByDDMTextFieldKeyword() throws Exception {
129 testOrderByDDMTextField("keyword");
130 }
131
132 public void testOrderByDDMTextFieldRepeatable() throws Exception {
133 testOrderByDDMFieldRepeatable(
134 new String[] {"B", "X|Y", "D|A|C|Z"},
135 new String[] {"D|A|C|Z", "B", "X|Y"}, "string",
136 DDMFormFieldType.TEXT);
137 }
138
139 protected static String[] toJsonArrays(String ... strings) {
140 String[] jsonArrays = new String[strings.length];
141
142 for (int i = 0; i < strings.length; i++) {
143 jsonArrays[i] = "[\"" + strings[i] + "\"]";
144 }
145
146 return jsonArrays;
147 }
148
149 protected TestOrderHelper(Group group) throws Exception {
150 _group = group;
151
152 _serviceContext = ServiceContextTestUtil.getServiceContext(
153 group.getGroupId());
154 }
155
156 protected DDMStructure addDDMStructure() throws Exception {
157 DDMForm ddmForm = DDMStructureTestUtil.getSampleDDMForm(
158 "name", _dataType, _indexType, _repeatable, _type,
159 new Locale[] {LocaleUtil.US}, LocaleUtil.US);
160
161 setDDMFormFieldOptions(ddmForm);
162
163 return DDMStructureTestUtil.addStructure(
164 _serviceContext.getScopeGroupId(),
165 getSearchableAssetEntryStructureClassName(), ddmForm);
166 }
167
168 protected DDMTemplate addDDMTemplate(DDMStructure ddmStructure)
169 throws Exception {
170
171 return DDMTemplateTestUtil.addTemplate(
172 _serviceContext.getScopeGroupId(), ddmStructure.getStructureId());
173 }
174
175 protected void addSearchableAssetEntries(
176 DDMStructure ddmStructure, DDMTemplate ddmTemplate)
177 throws Exception {
178
179 BaseModel<?> parentBaseModel = getSearchableAssetEntryParentBaseModel(
180 _group, _serviceContext);
181
182 for (String value : _unsortedValues) {
183 if (!_repeatable) {
184 addSearchableAssetEntry(
185 value, parentBaseModel, ddmStructure, ddmTemplate,
186 _serviceContext);
187 }
188 else {
189 addSearchableAssetEntryRepeatable(
190 StringUtil.split(value, CharPool.PIPE), parentBaseModel,
191 ddmStructure, ddmTemplate, _serviceContext);
192 }
193 }
194 }
195
196 protected abstract BaseModel<?> addSearchableAssetEntry(
197 String fieldValue, BaseModel<?> parentBaseModel,
198 DDMStructure ddmStructure, DDMTemplate ddmTemplate,
199 ServiceContext serviceContext)
200 throws Exception;
201
202 protected abstract BaseModel<?> addSearchableAssetEntryRepeatable(
203 String[] fieldValues, BaseModel<?> parentBaseModel,
204 DDMStructure ddmStructure, DDMTemplate ddmTemplate,
205 ServiceContext serviceContext)
206 throws Exception;
207
208 protected void assertSearch(AssetEntryQuery assetEntryQuery)
209 throws Exception {
210
211 Hits hits = search(assetEntryQuery);
212
213 List<AssetEntry> assetEntries = AssetUtil.getAssetEntries(hits);
214
215 Assert.assertEquals(
216 ArrayUtils.toString(_sortedValues),
217 ArrayUtils.toString(getValues(assetEntries)));
218 }
219
220 protected AssetEntryQuery createAssetEntryQuery(DDMStructure ddmStructure)
221 throws Exception {
222
223 AssetEntryQuery assetEntryQuery =
224 AssetEntryQueryTestUtil.createAssetEntryQuery(
225 _group.getGroupId(),
226 new String[] {getSearchableAssetEntryClassName()});
227
228 String orderByCol1 = DDMIndexerUtil.encodeName(
229 ddmStructure.getStructureId(), "name");
230
231 assetEntryQuery.setOrderByCol1(orderByCol1);
232 assetEntryQuery.setOrderByType1("asc");
233
234 return assetEntryQuery;
235 }
236
237 protected AssetRendererFactory getAssetRendererFactory() {
238 return AssetRendererFactoryRegistryUtil.
239 getAssetRendererFactoryByClassName(
240 getSearchableAssetEntryClassName());
241 }
242
243 protected abstract String getSearchableAssetEntryClassName();
244
245 protected abstract BaseModel<?> getSearchableAssetEntryParentBaseModel(
246 Group group, ServiceContext serviceContext) throws Exception;
247
248 protected abstract String getSearchableAssetEntryStructureClassName();
249
250 protected String getValue(AssetRenderer assetRenderer) throws Exception {
251 DDMFormValuesReader ddmFormValuesReader =
252 assetRenderer.getDDMFormValuesReader();
253
254 DDMFormValues ddmFormValues = ddmFormValuesReader.getDDMFormValues();
255
256 Map<String, List<DDMFormFieldValue>> ddmFormFieldValuesMap =
257 ddmFormValues.getDDMFormFieldValuesMap();
258
259 return ListUtil.toString(
260 ddmFormFieldValuesMap.get("name"),
261 new ValueAccessor(LocaleUtil.getDefault()) {
262
263 @Override
264 public String get(DDMFormFieldValue ddmFormFieldValue) {
265 Value value = ddmFormFieldValue.getValue();
266
267 return value.getString(locale);
268 }
269
270 },
271 StringPool.PIPE);
272 }
273
274 protected String[] getValues(List<AssetEntry> assetEntries)
275 throws Exception {
276
277 AssetRendererFactory assetRendererFactory = getAssetRendererFactory();
278
279 String[] values = new String[assetEntries.size()];
280
281 for (int i = 0; i < assetEntries.size(); i++) {
282 AssetEntry assetEntry = assetEntries.get(i);
283
284 AssetRenderer assetRenderer = assetRendererFactory.getAssetRenderer(
285 assetEntry.getClassPK());
286
287 values[i] = getValue(assetRenderer);
288 }
289
290 return values;
291 }
292
293 protected Hits search(AssetEntryQuery assetEntryQuery) throws Exception {
294 SearchContext searchContext = SearchContextTestUtil.getSearchContext();
295
296 searchContext.setGroupIds(assetEntryQuery.getGroupIds());
297
298 return AssetUtil.search(
299 searchContext, assetEntryQuery, QueryUtil.ALL_POS,
300 QueryUtil.ALL_POS);
301 }
302
303 protected void setDDMFormFieldOptions(DDMForm ddmForm) {
304 if (!_type.equals(DDMFormFieldType.RADIO)) {
305 return;
306 }
307
308 List<DDMFormField> ddmFormFields = ddmForm.getDDMFormFields();
309
310 DDMFormField ddmFormField = ddmFormFields.get(0);
311
312 DDMFormFieldOptions ddmFormFieldOptions = new DDMFormFieldOptions();
313
314 for (String option : _unsortedValues) {
315 ddmFormFieldOptions.addOptionLabel(option, LocaleUtil.US, option);
316 }
317
318 ddmFormField.setDDMFormFieldOptions(ddmFormFieldOptions);
319 }
320
321 protected void testOrderByDDMField() throws Exception {
322 DDMStructure ddmStructure = addDDMStructure();
323
324 DDMTemplate ddmTemplate = addDDMTemplate(ddmStructure);
325
326 addSearchableAssetEntries(ddmStructure, ddmTemplate);
327
328 final AssetEntryQuery assetEntryQuery = createAssetEntryQuery(
329 ddmStructure);
330
331 IdempotentRetryAssert.retryAssert(
332 3, TimeUnit.SECONDS,
333 new Callable<Void>() {
334
335 @Override
336 public Void call() throws Exception {
337 assertSearch(assetEntryQuery);
338
339 return null;
340 }
341
342 });
343 }
344
345 protected void testOrderByDDMField(
346 String[] unsortedValues, String[] sortedValues, String dataType,
347 String type)
348 throws Exception {
349
350 testOrderByDDMField(
351 unsortedValues, sortedValues, dataType, "text", type);
352 }
353
354 protected void testOrderByDDMField(
355 String[] unsortedValues, String[] sortedValues, String dataType,
356 String indexType, String type)
357 throws Exception {
358
359 _unsortedValues = unsortedValues;
360 _sortedValues = sortedValues;
361 _dataType = dataType;
362 _indexType = indexType;
363 _type = type;
364 _repeatable = false;
365
366 testOrderByDDMField();
367 }
368
369 protected void testOrderByDDMFieldRepeatable(
370 String[] unsortedValues, String[] sortedValues, String dataType,
371 String type)
372 throws Exception {
373
374 _unsortedValues = unsortedValues;
375 _sortedValues = sortedValues;
376 _dataType = dataType;
377 _indexType = "text";
378 _type = type;
379 _repeatable = true;
380
381 testOrderByDDMField();
382 }
383
384 protected void testOrderByDDMRadioField(String indexType) throws Exception {
385 testOrderByDDMField(
386 toJsonArrays("a", "D", "c", "B"), toJsonArrays("a", "B", "c", "D"),
387 FieldConstants.STRING, indexType, DDMFormFieldType.RADIO);
388 }
389
390 protected void testOrderByDDMTextField(String indexType) throws Exception {
391 testOrderByDDMField(
392 new String[] {"a", "D", "c", "B"},
393 new String[] {"a", "B", "c", "D"}, FieldConstants.STRING, indexType,
394 DDMFormFieldType.TEXT);
395 }
396
397 private String _dataType;
398 private final Group _group;
399 private String _indexType;
400 private boolean _repeatable;
401 private final ServiceContext _serviceContext;
402 private String[] _sortedValues;
403 private String _type;
404 private String[] _unsortedValues;
405
406 }