001
014
015 package com.liferay.portal.kernel.search;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
018 import com.liferay.portal.kernel.util.ArrayUtil;
019 import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
020 import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
021 import com.liferay.portal.kernel.util.FileUtil;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.LocaleUtil;
024 import com.liferay.portal.kernel.util.PropsKeys;
025 import com.liferay.portal.kernel.util.PropsUtil;
026 import com.liferay.portal.kernel.util.SetUtil;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.StringUtil;
030 import com.liferay.portal.kernel.util.Validator;
031
032 import java.io.File;
033 import java.io.FileInputStream;
034 import java.io.IOException;
035 import java.io.InputStream;
036
037 import java.text.DateFormat;
038 import java.text.Format;
039 import java.text.ParseException;
040
041 import java.util.Arrays;
042 import java.util.Collections;
043 import java.util.Date;
044 import java.util.HashMap;
045 import java.util.Locale;
046 import java.util.Map;
047 import java.util.Set;
048
049
053 public class DocumentImpl implements Document {
054
055 public static String getLocalizedName(Locale locale, String name) {
056 if (locale == null) {
057 return name;
058 }
059
060 String languageId = LocaleUtil.toLanguageId(locale);
061
062 return getLocalizedName(languageId, name);
063 }
064
065 public static String getLocalizedName(String languageId, String name) {
066 return name.concat(StringPool.UNDERLINE).concat(languageId);
067 }
068
069 public static String getSortableFieldName(String name) {
070 return name.concat(StringPool.UNDERLINE).concat(_SORTABLE_FIELD_SUFFIX);
071 }
072
073 public static String getSortFieldName(Sort sort, String scoreFieldName) {
074 if (sort.getType() == Sort.SCORE_TYPE) {
075 return scoreFieldName;
076 }
077
078 String fieldName = sort.getFieldName();
079
080 if (DocumentImpl.isSortableFieldName(fieldName)) {
081 return fieldName;
082 }
083
084 if ((sort.getType() == Sort.STRING_TYPE) &&
085 !DocumentImpl.isSortableTextField(fieldName)) {
086
087 return scoreFieldName;
088 }
089
090 return DocumentImpl.getSortableFieldName(fieldName);
091 }
092
093 public static boolean isSortableFieldName(String name) {
094 return name.endsWith(_SORTABLE_FIELD_SUFFIX);
095 }
096
097 public static boolean isSortableTextField(String name) {
098 return _defaultSortableTextFields.contains(name);
099 }
100
101 @Override
102 public void add(Field field) {
103 _fields.put(field.getName(), field);
104 }
105
106 @Override
107 public void addDate(String name, Date value) {
108 if (value == null) {
109 return;
110 }
111
112 addDate(name, new Date[] {value});
113 }
114
115 @Override
116 public void addDate(String name, Date[] values) {
117 if (values == null) {
118 return;
119 }
120
121 String[] dates = new String[values.length];
122 Long[] datesTime = new Long[values.length];
123
124 for (int i = 0; i < values.length; i++) {
125 dates[i] = _dateFormat.format(values[i]);
126 datesTime[i] = values[i].getTime();
127 }
128
129 createSortableNumericField(name, false, datesTime);
130
131 addKeyword(name, dates);
132 }
133
134 @Override
135 public void addDateSortable(String name, Date value) {
136 if (value == null) {
137 return;
138 }
139
140 addDateSortable(name, new Date[] {value});
141 }
142
143 @Override
144 public void addDateSortable(String name, Date[] values) {
145 if (values == null) {
146 return;
147 }
148
149 String[] dates = new String[values.length];
150 Long[] datesTime = new Long[values.length];
151
152 for (int i = 0; i < values.length; i++) {
153 dates[i] = _dateFormat.format(values[i]);
154 datesTime[i] = values[i].getTime();
155 }
156
157 createSortableNumericField(name, true, datesTime);
158
159 addKeyword(name, dates);
160 }
161
162 @Override
163 public void addFile(String name, byte[] bytes, String fileExt) {
164 InputStream is = new UnsyncByteArrayInputStream(bytes);
165
166 addFile(name, is, fileExt);
167 }
168
169 @Override
170 public void addFile(String name, File file, String fileExt)
171 throws IOException {
172
173 InputStream is = new FileInputStream(file);
174
175 addFile(name, is, fileExt);
176 }
177
178 @Override
179 public void addFile(String name, InputStream is, String fileExt) {
180 addText(name, FileUtil.extractText(is, fileExt));
181 }
182
183 @Override
184 public void addFile(
185 String name, InputStream is, String fileExt, int maxStringLength) {
186
187 addText(name, FileUtil.extractText(is, fileExt, maxStringLength));
188 }
189
190 @Override
191 public void addKeyword(String name, boolean value) {
192 addKeyword(name, String.valueOf(value));
193 }
194
195 @Override
196 public void addKeyword(String name, Boolean value) {
197 addKeyword(name, String.valueOf(value));
198 }
199
200 @Override
201 public void addKeyword(String name, boolean[] values) {
202 if (values == null) {
203 return;
204 }
205
206 addKeyword(name, ArrayUtil.toStringArray(values));
207 }
208
209 @Override
210 public void addKeyword(String name, Boolean[] values) {
211 if (values == null) {
212 return;
213 }
214
215 addKeyword(name, ArrayUtil.toStringArray(values));
216 }
217
218 @Override
219 public void addKeyword(String name, double value) {
220 addKeyword(name, String.valueOf(value));
221 }
222
223 @Override
224 public void addKeyword(String name, Double value) {
225 addKeyword(name, String.valueOf(value));
226 }
227
228 @Override
229 public void addKeyword(String name, double[] values) {
230 if (values == null) {
231 return;
232 }
233
234 addKeyword(name, ArrayUtil.toStringArray(values));
235 }
236
237 @Override
238 public void addKeyword(String name, Double[] values) {
239 if (values == null) {
240 return;
241 }
242
243 addKeyword(name, ArrayUtil.toStringArray(values));
244 }
245
246 @Override
247 public void addKeyword(String name, float value) {
248 addKeyword(name, String.valueOf(value));
249 }
250
251 @Override
252 public void addKeyword(String name, Float value) {
253 addKeyword(name, String.valueOf(value));
254 }
255
256 @Override
257 public void addKeyword(String name, float[] values) {
258 if (values == null) {
259 return;
260 }
261
262 addKeyword(name, ArrayUtil.toStringArray(values));
263 }
264
265 @Override
266 public void addKeyword(String name, Float[] values) {
267 if (values == null) {
268 return;
269 }
270
271 addKeyword(name, ArrayUtil.toStringArray(values));
272 }
273
274 @Override
275 public void addKeyword(String name, int value) {
276 addKeyword(name, String.valueOf(value));
277 }
278
279 @Override
280 public void addKeyword(String name, int[] values) {
281 if (values == null) {
282 return;
283 }
284
285 addKeyword(name, ArrayUtil.toStringArray(values));
286 }
287
288 @Override
289 public void addKeyword(String name, Integer value) {
290 addKeyword(name, String.valueOf(value));
291 }
292
293 @Override
294 public void addKeyword(String name, Integer[] values) {
295 if (values == null) {
296 return;
297 }
298
299 addKeyword(name, ArrayUtil.toStringArray(values));
300 }
301
302 @Override
303 public void addKeyword(String name, long value) {
304 addKeyword(name, String.valueOf(value));
305 }
306
307 @Override
308 public void addKeyword(String name, Long value) {
309 addKeyword(name, String.valueOf(value));
310 }
311
312 @Override
313 public void addKeyword(String name, long[] values) {
314 if (values == null) {
315 return;
316 }
317
318 addKeyword(name, ArrayUtil.toStringArray(values));
319 }
320
321 @Override
322 public void addKeyword(String name, Long[] values) {
323 if (values == null) {
324 return;
325 }
326
327 addKeyword(name, ArrayUtil.toStringArray(values));
328 }
329
330 @Override
331 public void addKeyword(String name, short value) {
332 addKeyword(name, String.valueOf(value));
333 }
334
335 @Override
336 public void addKeyword(String name, Short value) {
337 addKeyword(name, String.valueOf(value));
338 }
339
340 @Override
341 public void addKeyword(String name, short[] values) {
342 if (values == null) {
343 return;
344 }
345
346 addKeyword(name, ArrayUtil.toStringArray(values));
347 }
348
349 @Override
350 public void addKeyword(String name, Short[] values) {
351 if (values == null) {
352 return;
353 }
354
355 addKeyword(name, ArrayUtil.toStringArray(values));
356 }
357
358 @Override
359 public void addKeyword(String name, String value) {
360 addKeyword(name, value, false);
361 }
362
363 @Override
364 public void addKeyword(String name, String value, boolean lowerCase) {
365 createKeywordField(name, value, lowerCase);
366
367 createSortableKeywordField(name, value);
368 }
369
370 @Override
371 public void addKeyword(String name, String[] values) {
372 if (values == null) {
373 return;
374 }
375
376 Field field = new Field(name, values);
377
378 _fields.put(name, field);
379 }
380
381 @Override
382 public void addKeywordSortable(String name, Boolean value) {
383 String valueString = String.valueOf(value);
384
385 createKeywordField(name, valueString, false);
386
387 createSortableTextField(name, valueString);
388 }
389
390 @Override
391 public void addKeywordSortable(String name, Boolean[] values) {
392 if (values == null) {
393 return;
394 }
395
396 String[] valuesString = ArrayUtil.toStringArray(values);
397
398 Field field = new Field(name, valuesString);
399
400 _fields.put(name, field);
401
402 createSortableTextField(name, valuesString);
403 }
404
405 @Override
406 public void addKeywordSortable(String name, String value) {
407 createKeywordField(name, value, false);
408
409 createSortableTextField(name, value);
410 }
411
412 @Override
413 public void addKeywordSortable(String name, String[] values) {
414 Field field = new Field(name, values);
415
416 _fields.put(name, field);
417
418 createSortableTextField(name, values);
419 }
420
421 @Override
422 public void addLocalizedKeyword(String name, Map<Locale, String> values) {
423 addLocalizedKeyword(name, values, false);
424 }
425
426 @Override
427 public void addLocalizedKeyword(
428 String name, Map<Locale, String> values, boolean lowerCase) {
429
430 if ((values == null) || values.isEmpty()) {
431 return;
432 }
433
434 if (lowerCase) {
435 Map<Locale, String> lowerCaseValues = new HashMap<Locale, String>(
436 values.size());
437
438 for (Map.Entry<Locale, String> entry : values.entrySet()) {
439 String value = GetterUtil.getString(entry.getValue());
440
441 lowerCaseValues.put(
442 entry.getKey(), StringUtil.toLowerCase(value));
443 }
444
445 values = lowerCaseValues;
446 }
447
448 Field field = new Field(name, values);
449
450 _fields.put(name, field);
451 }
452
453 @Override
454 public void addLocalizedKeyword(
455 String name, Map<Locale, String> values, boolean lowerCase,
456 boolean sortable) {
457
458 if ((values == null) || values.isEmpty()) {
459 return;
460 }
461
462 if (lowerCase) {
463 Map<Locale, String> lowerCaseValues = new HashMap<Locale, String>(
464 values.size());
465
466 for (Map.Entry<Locale, String> entry : values.entrySet()) {
467 String value = GetterUtil.getString(entry.getValue());
468
469 lowerCaseValues.put(
470 entry.getKey(), StringUtil.toLowerCase(value));
471 }
472
473 values = lowerCaseValues;
474 }
475
476 Field field = new Field(name, values);
477
478 field.setSortable(sortable);
479
480 _fields.put(name, field);
481 }
482
483 @Override
484 public void addLocalizedText(String name, Map<Locale, String> values) {
485 if ((values == null) || values.isEmpty()) {
486 return;
487 }
488
489 Field field = new Field(name, values);
490
491 field.setTokenized(true);
492
493 _fields.put(name, field);
494 }
495
496
499 @Override
500 public void addModifiedDate() {
501 addModifiedDate(new Date());
502 }
503
504
507 @Override
508 public void addModifiedDate(Date modifiedDate) {
509 addDate(Field.MODIFIED, modifiedDate);
510 }
511
512 @Override
513 public void addNumber(String name, double value) {
514 createNumberField(name, Double.valueOf(value));
515 }
516
517 @Override
518 public void addNumber(String name, Double value) {
519 createNumberField(name, value);
520 }
521
522 @Override
523 public void addNumber(String name, double[] values) {
524 if (values == null) {
525 return;
526 }
527
528 createNumberField(name, ArrayUtil.toArray(values));
529 }
530
531 @Override
532 public void addNumber(String name, Double[] values) {
533 createNumberField(name, values);
534 }
535
536 @Override
537 public void addNumber(String name, float value) {
538 createNumberField(name, Float.valueOf(value));
539 }
540
541 @Override
542 public void addNumber(String name, Float value) {
543 createNumberField(name, value);
544 }
545
546 @Override
547 public void addNumber(String name, float[] values) {
548 if (values == null) {
549 return;
550 }
551
552 createNumberField(name, ArrayUtil.toArray(values));
553 }
554
555 @Override
556 public void addNumber(String name, Float[] values) {
557 createNumberField(name, values);
558 }
559
560 @Override
561 public void addNumber(String name, int value) {
562 createNumberField(name, Integer.valueOf(value));
563 }
564
565 @Override
566 public void addNumber(String name, int[] values) {
567 if (values == null) {
568 return;
569 }
570
571 createNumberField(name, ArrayUtil.toArray(values));
572 }
573
574 @Override
575 public void addNumber(String name, Integer value) {
576 createNumberField(name, value);
577 }
578
579 @Override
580 public void addNumber(String name, Integer[] values) {
581 createNumberField(name, values);
582 }
583
584 @Override
585 public void addNumber(String name, long value) {
586 createNumberField(name, Long.valueOf(value));
587 }
588
589 @Override
590 public void addNumber(String name, Long value) {
591 createNumberField(name, value);
592 }
593
594 @Override
595 public void addNumber(String name, long[] values) {
596 if (values == null) {
597 return;
598 }
599
600 createNumberField(name, ArrayUtil.toArray(values));
601 }
602
603 @Override
604 public void addNumber(String name, Long[] values) {
605 createNumberField(name, values);
606 }
607
608 @Override
609 public void addNumber(String name, String value) {
610 createNumberField(name, Long.valueOf(value));
611 }
612
613
616 @Deprecated
617 public void addNumber(
618 String name, String value, Class<? extends Number> clazz) {
619
620 if (Validator.isNull(value)) {
621 return;
622 }
623
624 addNumber(name, new String[] {value}, clazz);
625 }
626
627 @Override
628 public void addNumber(String name, String[] values) {
629 if (values == null) {
630 return;
631 }
632
633 Long[] longs = new Long[values.length];
634
635 for (int i = 0; i < values.length; i++) {
636 longs[i] = Long.valueOf(values[i]);
637 }
638
639 createNumberField(name, longs);
640 }
641
642
645 @Deprecated
646 public void addNumber(
647 String name, String[] values, Class<? extends Number> clazz) {
648
649 if (values == null) {
650 return;
651 }
652
653 String sortableFieldName = getSortableFieldName(name);
654
655 Field field = new Field(sortableFieldName, values);
656
657 field.setNumeric(true);
658 field.setNumericClass(clazz);
659
660 _fields.put(sortableFieldName, field);
661
662 addKeyword(name, values);
663 }
664
665 @Override
666 public void addNumberSortable(String name, Double value) {
667 createNumberFieldWithTypedSortable(name, value);
668 }
669
670 @Override
671 public void addNumberSortable(String name, Double[] values) {
672 createNumberFieldWithTypedSortable(name, values);
673 }
674
675 @Override
676 public void addNumberSortable(String name, Float value) {
677 createNumberFieldWithTypedSortable(name, value);
678 }
679
680 @Override
681 public void addNumberSortable(String name, Float[] values) {
682 createNumberFieldWithTypedSortable(name, values);
683 }
684
685 @Override
686 public void addNumberSortable(String name, Integer value) {
687 createNumberFieldWithTypedSortable(name, value);
688 }
689
690 @Override
691 public void addNumberSortable(String name, Integer[] values) {
692 createNumberFieldWithTypedSortable(name, values);
693 }
694
695 @Override
696 public void addNumberSortable(String name, Long value) {
697 createNumberFieldWithTypedSortable(name, value);
698 }
699
700 @Override
701 public void addNumberSortable(String name, Long[] values) {
702 createNumberFieldWithTypedSortable(name, values);
703 }
704
705 @Override
706 public void addText(String name, String value) {
707 if (Validator.isNull(value)) {
708 return;
709 }
710
711 Field field = new Field(name, value);
712
713 field.setTokenized(true);
714
715 _fields.put(name, field);
716
717 createSortableKeywordField(name, value);
718 }
719
720 @Override
721 public void addText(String name, String[] values) {
722 if (values == null) {
723 return;
724 }
725
726 Field field = new Field(name, values);
727
728 field.setTokenized(true);
729
730 _fields.put(name, field);
731
732 createSortableKeywordField(name, values);
733 }
734
735 @Override
736 public void addTextSortable(String name, String value) {
737 if (Validator.isNull(value)) {
738 return;
739 }
740
741 Field field = new Field(name, value);
742
743 field.setTokenized(true);
744
745 _fields.put(name, field);
746
747 createSortableTextField(name, value);
748 }
749
750 @Override
751 public void addTextSortable(String name, String[] values) {
752 if (values == null) {
753 return;
754 }
755
756 Field field = new Field(name, values);
757
758 field.setTokenized(true);
759
760 _fields.put(name, field);
761
762 createSortableTextField(name, values);
763 }
764
765 @Override
766 public void addUID(String portletId, long field1) {
767 addUID(portletId, String.valueOf(field1));
768 }
769
770 @Override
771 public void addUID(String portletId, long field1, String field2) {
772 addUID(portletId, String.valueOf(field1), field2);
773 }
774
775 @Override
776 public void addUID(String portletId, Long field1) {
777 addUID(portletId, field1.longValue());
778 }
779
780 @Override
781 public void addUID(String portletId, Long field1, String field2) {
782 addUID(portletId, field1.longValue(), field2);
783 }
784
785 @Override
786 public void addUID(String portletId, String field1) {
787 addUID(portletId, field1, null);
788 }
789
790 @Override
791 public void addUID(String portletId, String field1, String field2) {
792 addUID(portletId, field1, field2, null);
793 }
794
795 @Override
796 public void addUID(
797 String portletId, String field1, String field2, String field3) {
798
799 addUID(portletId, field1, field2, field3, null);
800 }
801
802 @Override
803 public void addUID(
804 String portletId, String field1, String field2, String field3,
805 String field4) {
806
807 String uid = portletId + _UID_PORTLET + field1;
808
809 if (field2 != null) {
810 uid += _UID_FIELD + field2;
811 }
812
813 if (field3 != null) {
814 uid += _UID_FIELD + field3;
815 }
816
817 if (field4 != null) {
818 uid += _UID_FIELD + field4;
819 }
820
821 addKeyword(Field.UID, uid);
822 }
823
824 @Override
825 public Object clone() {
826 DocumentImpl documentImpl = new DocumentImpl();
827
828 documentImpl.setSortableTextFields(_sortableTextFields);
829
830 return documentImpl;
831 }
832
833 @Override
834 public String get(Locale locale, String name) {
835 if (locale == null) {
836 return get(name);
837 }
838
839 String localizedName = getLocalizedName(locale, name);
840
841 Field field = _fields.get(localizedName);
842
843 if (field == null) {
844 field = _fields.get(name);
845 }
846
847 if (field == null) {
848 return StringPool.BLANK;
849 }
850
851 return field.getValue();
852 }
853
854 @Override
855 public String get(Locale locale, String name, String defaultName) {
856 if (locale == null) {
857 return get(name, defaultName);
858 }
859
860 String localizedName = getLocalizedName(locale, name);
861
862 Field field = _fields.get(localizedName);
863
864 if (field == null) {
865 localizedName = getLocalizedName(locale, defaultName);
866
867 field = _fields.get(localizedName);
868 }
869
870 if (field == null) {
871 return StringPool.BLANK;
872 }
873
874 return field.getValue();
875 }
876
877 @Override
878 public String get(String name) {
879 Field field = _fields.get(name);
880
881 if (field == null) {
882 return StringPool.BLANK;
883 }
884
885 return field.getValue();
886 }
887
888 @Override
889 public String get(String name, String defaultName) {
890 Field field = _fields.get(name);
891
892 if (field == null) {
893 return get(defaultName);
894 }
895
896 return field.getValue();
897 }
898
899 @Override
900 public Date getDate(String name) throws ParseException {
901 DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
902 _INDEX_DATE_FORMAT_PATTERN);
903
904 return dateFormat.parse(get(name));
905 }
906
907 @Override
908 public Field getField(String name) {
909 return _fields.get(name);
910 }
911
912 @Override
913 public Map<String, Field> getFields() {
914 return _fields;
915 }
916
917 @Override
918 public String getPortletId() {
919 String uid = getUID();
920
921 int pos = uid.indexOf(_UID_PORTLET);
922
923 return uid.substring(0, pos);
924 }
925
926 @Override
927 public String getUID() {
928 Field field = _fields.get(Field.UID);
929
930 if (field == null) {
931 throw new RuntimeException("UID is not set");
932 }
933
934 return field.getValue();
935 }
936
937 @Override
938 public String[] getValues(String name) {
939 Field field = _fields.get(name);
940
941 if (field == null) {
942 return new String[] {StringPool.BLANK};
943 }
944
945 return field.getValues();
946 }
947
948 @Override
949 public boolean hasField(String name) {
950 if (_fields.containsKey(name)) {
951 return true;
952 }
953
954 return false;
955 }
956
957 @Override
958 public boolean isDocumentSortableTextField(String name) {
959 return _sortableTextFields.contains(name);
960 }
961
962 @Override
963 public void remove(String name) {
964 _fields.remove(name);
965 }
966
967 public void setFields(Map<String, Field> fields) {
968 _fields = fields;
969 }
970
971 @Override
972 public void setSortableTextFields(String[] sortableTextFields) {
973 _sortableTextFields = SetUtil.fromArray(sortableTextFields);
974 }
975
976 @Override
977 public String toString() {
978 StringBundler sb = new StringBundler();
979
980 sb.append(StringPool.OPEN_CURLY_BRACE);
981
982 boolean firstField = true;
983
984 for (Field field : _fields.values()) {
985 if (!firstField) {
986 sb.append(StringPool.COMMA);
987 sb.append(StringPool.SPACE);
988 }
989 else {
990 firstField = false;
991 }
992
993 sb.append(field.getName());
994 sb.append(StringPool.EQUAL);
995 sb.append(Arrays.toString(field.getValues()));
996 }
997
998 sb.append(StringPool.CLOSE_CURLY_BRACE);
999
1000 return sb.toString();
1001 }
1002
1003 protected void createKeywordField(
1004 String name, String value, boolean lowerCase) {
1005
1006 if (lowerCase && Validator.isNotNull(value)) {
1007 value = StringUtil.toLowerCase(value);
1008 }
1009
1010 Field field = new Field(name, value);
1011
1012 _fields.put(name, field);
1013
1014 for (String fieldName : Field.UNSCORED_FIELD_NAMES) {
1015 if (StringUtil.equalsIgnoreCase(name, fieldName)) {
1016 field.setBoost(0);
1017 }
1018 }
1019 }
1020
1021 protected void createNumberField(
1022 String name, boolean typify, Number value) {
1023
1024 if (value == null) {
1025 return;
1026 }
1027
1028 String valueString = String.valueOf(value);
1029
1030 createSortableNumericField(name, typify, valueString, value.getClass());
1031
1032 Field field = new Field(name, valueString);
1033
1034 _fields.put(name, field);
1035 }
1036
1037 protected <T extends Number & Comparable<? super T>> void createNumberField(
1038 String name, boolean typify, T... values) {
1039
1040 if (values == null) {
1041 return;
1042 }
1043
1044 createSortableNumericField(name, typify, values);
1045
1046 Field field = new Field(name, ArrayUtil.toStringArray(values));
1047
1048 _fields.put(name, field);
1049 }
1050
1051 protected void createNumberField(String name, Number value) {
1052 createNumberField(name, false, value);
1053 }
1054
1055 protected <T extends Number & Comparable<? super T>> void createNumberField(
1056 String name, T... values) {
1057
1058 createNumberField(name, false, values);
1059 }
1060
1061 protected void createNumberFieldWithTypedSortable(
1062 String name, Number value) {
1063
1064 createNumberField(name, true, value);
1065 }
1066
1067 protected <T extends Number & Comparable<? super T>> void
1068 createNumberFieldWithTypedSortable(String name, T... values) {
1069
1070 createNumberField(name, true, values);
1071 }
1072
1073 protected void createSortableKeywordField(String name, String value) {
1074 if (isDocumentSortableTextField(name)) {
1075 createSortableTextField(name, value);
1076 }
1077 }
1078
1079 protected void createSortableKeywordField(String name, String[] values) {
1080 if (isDocumentSortableTextField(name)) {
1081 createSortableTextField(name, values);
1082 }
1083 }
1084
1085 protected void createSortableNumericField(
1086 String name, boolean typify, String value,
1087 Class<? extends Number> clazz) {
1088
1089 if (typify) {
1090 name = name.concat(StringPool.UNDERLINE).concat("Number");
1091 }
1092
1093 String sortableFieldName = getSortableFieldName(name);
1094
1095 Field field = new Field(sortableFieldName, value);
1096
1097 _fields.put(sortableFieldName, field);
1098
1099 field.setNumeric(true);
1100 field.setNumericClass(clazz);
1101 }
1102
1103 protected <T extends Number & Comparable<? super T>> void
1104 createSortableNumericField(String name, boolean typify, T... values) {
1105
1106 if ((values == null) || (values.length == 0)) {
1107 return;
1108 }
1109
1110 T minValue = Collections.min(Arrays.asList(values));
1111
1112 createSortableNumericField(
1113 name, typify, String.valueOf(minValue), minValue.getClass());
1114 }
1115
1116 protected void createSortableTextField(String name, String value) {
1117 String truncatedValue = value;
1118
1119 if (value.length() > _SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH) {
1120 truncatedValue = value.substring(
1121 0, _SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH);
1122 }
1123
1124 createKeywordField(getSortableFieldName(name), truncatedValue, true);
1125 }
1126
1127 protected void createSortableTextField(String name, String[] values) {
1128 if (values.length == 0) {
1129 return;
1130 }
1131
1132 createSortableTextField(name, Collections.min(Arrays.asList(values)));
1133 }
1134
1135 protected void setSortableTextFields(Set<String> sortableTextFields) {
1136 _sortableTextFields = sortableTextFields;
1137 }
1138
1139 private static final String _INDEX_DATE_FORMAT_PATTERN = PropsUtil.get(
1140 PropsKeys.INDEX_DATE_FORMAT_PATTERN);
1141
1142 private static final String _SORTABLE_FIELD_SUFFIX = "sortable";
1143
1144 private static final int _SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH =
1145 GetterUtil.getInteger(
1146 PropsUtil.get(
1147 PropsKeys.INDEX_SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH));
1148
1149 private static final String _UID_FIELD = "_FIELD_";
1150
1151 private static final String _UID_PORTLET = "_PORTLET_";
1152
1153 private static Format _dateFormat =
1154 FastDateFormatFactoryUtil.getSimpleDateFormat(
1155 _INDEX_DATE_FORMAT_PATTERN);
1156 private static Set<String> _defaultSortableTextFields = SetUtil.fromArray(
1157 PropsUtil.getArray(PropsKeys.INDEX_SORTABLE_TEXT_FIELDS));
1158
1159 private Map<String, Field> _fields = new HashMap<String, Field>();
1160 private Set<String> _sortableTextFields = _defaultSortableTextFields;
1161
1162 }