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.Validator;
030
031 import java.io.File;
032 import java.io.FileInputStream;
033 import java.io.IOException;
034 import java.io.InputStream;
035
036 import java.text.DateFormat;
037 import java.text.Format;
038 import java.text.ParseException;
039
040 import java.util.Arrays;
041 import java.util.Date;
042 import java.util.HashMap;
043 import java.util.Locale;
044 import java.util.Map;
045 import java.util.Set;
046
047
051 public class DocumentImpl implements Document {
052
053 public static String getLocalizedName(Locale locale, String name) {
054 if (locale == null) {
055 return name;
056 }
057
058 String languageId = LocaleUtil.toLanguageId(locale);
059
060 String localizedName = name.concat(StringPool.UNDERLINE).concat(
061 languageId);
062
063 return localizedName;
064 }
065
066 public static String getSortableFieldName(String name) {
067 return name.concat(StringPool.UNDERLINE).concat(
068 _SORTABLE_TEXT_FIELD_SUFFIX);
069 }
070
071 public static boolean isSortableTextField(String name) {
072 return _defaultSortableTextFields.contains(name);
073 }
074
075 public void add(Field field) {
076 _fields.put(field.getName(), field);
077 }
078
079 public void addDate(String name, Date value) {
080 if (value == null) {
081 return;
082 }
083
084 addKeyword(name, _dateFormat.format(value));
085 }
086
087 public void addDate(String name, Date[] values) {
088 if (values == null) {
089 return;
090 }
091
092 String[] dates = new String[values.length];
093
094 for (int i = 0; i < values.length; i++) {
095 dates[i] = _dateFormat.format(values[i]);
096 }
097
098 addKeyword(name, dates);
099 }
100
101 public void addFile(String name, byte[] bytes, String fileExt) {
102 InputStream is = new UnsyncByteArrayInputStream(bytes);
103
104 addFile(name, is, fileExt);
105 }
106
107 public void addFile(String name, File file, String fileExt)
108 throws IOException {
109
110 InputStream is = new FileInputStream(file);
111
112 addFile(name, is, fileExt);
113 }
114
115 public void addFile(String name, InputStream is, String fileExt) {
116 addText(name, FileUtil.extractText(is, fileExt));
117 }
118
119 public void addKeyword(String name, boolean value) {
120 addKeyword(name, String.valueOf(value));
121 }
122
123 public void addKeyword(String name, Boolean value) {
124 addKeyword(name, String.valueOf(value));
125 }
126
127 public void addKeyword(String name, boolean[] values) {
128 if (values == null) {
129 return;
130 }
131
132 addKeyword(name, ArrayUtil.toStringArray(values));
133 }
134
135 public void addKeyword(String name, Boolean[] values) {
136 if (values == null) {
137 return;
138 }
139
140 addKeyword(name, ArrayUtil.toStringArray(values));
141 }
142
143 public void addKeyword(String name, double value) {
144 addKeyword(name, String.valueOf(value));
145 }
146
147 public void addKeyword(String name, Double value) {
148 addKeyword(name, String.valueOf(value));
149 }
150
151 public void addKeyword(String name, double[] values) {
152 if (values == null) {
153 return;
154 }
155
156 addKeyword(name, ArrayUtil.toStringArray(values));
157 }
158
159 public void addKeyword(String name, Double[] values) {
160 if (values == null) {
161 return;
162 }
163
164 addKeyword(name, ArrayUtil.toStringArray(values));
165 }
166
167 public void addKeyword(String name, float value) {
168 addKeyword(name, String.valueOf(value));
169 }
170
171 public void addKeyword(String name, Float value) {
172 addKeyword(name, String.valueOf(value));
173 }
174
175 public void addKeyword(String name, float[] values) {
176 if (values == null) {
177 return;
178 }
179
180 addKeyword(name, ArrayUtil.toStringArray(values));
181 }
182
183 public void addKeyword(String name, Float[] values) {
184 if (values == null) {
185 return;
186 }
187
188 addKeyword(name, ArrayUtil.toStringArray(values));
189 }
190
191 public void addKeyword(String name, int value) {
192 addKeyword(name, String.valueOf(value));
193 }
194
195 public void addKeyword(String name, int[] values) {
196 if (values == null) {
197 return;
198 }
199
200 addKeyword(name, ArrayUtil.toStringArray(values));
201 }
202
203 public void addKeyword(String name, Integer value) {
204 addKeyword(name, String.valueOf(value));
205 }
206
207 public void addKeyword(String name, Integer[] values) {
208 if (values == null) {
209 return;
210 }
211
212 addKeyword(name, ArrayUtil.toStringArray(values));
213 }
214
215 public void addKeyword(String name, long value) {
216 addKeyword(name, String.valueOf(value));
217 }
218
219 public void addKeyword(String name, Long value) {
220 addKeyword(name, String.valueOf(value));
221 }
222
223 public void addKeyword(String name, long[] values) {
224 if (values == null) {
225 return;
226 }
227
228 addKeyword(name, ArrayUtil.toStringArray(values));
229 }
230
231 public void addKeyword(String name, Long[] values) {
232 if (values == null) {
233 return;
234 }
235
236 addKeyword(name, ArrayUtil.toStringArray(values));
237 }
238
239 public void addKeyword(String name, short value) {
240 addKeyword(name, String.valueOf(value));
241 }
242
243 public void addKeyword(String name, Short value) {
244 addKeyword(name, String.valueOf(value));
245 }
246
247 public void addKeyword(String name, short[] values) {
248 if (values == null) {
249 return;
250 }
251
252 addKeyword(name, ArrayUtil.toStringArray(values));
253 }
254
255 public void addKeyword(String name, Short[] values) {
256 if (values == null) {
257 return;
258 }
259
260 addKeyword(name, ArrayUtil.toStringArray(values));
261 }
262
263 public void addKeyword(String name, String value) {
264 addKeyword(name, value, false);
265 }
266
267 public void addKeyword(String name, String value, boolean lowerCase) {
268 if (lowerCase && Validator.isNotNull(value)) {
269 value = value.toLowerCase();
270 }
271
272 Field field = new Field(name, value);
273
274 for (String fieldName : Field.UNSCORED_FIELD_NAMES) {
275 if (name.equalsIgnoreCase(fieldName)) {
276 field.setBoost(0);
277 }
278 }
279
280 _fields.put(name, field);
281 }
282
283 public void addKeyword(String name, String[] values) {
284 if (values == null) {
285 return;
286 }
287
288 Field field = new Field(name, values);
289
290 _fields.put(name, field);
291 }
292
293 public void addLocalizedKeyword(String name, Map<Locale, String> values) {
294 addLocalizedKeyword(name, values, false);
295 }
296
297 public void addLocalizedKeyword(
298 String name, Map<Locale, String> values, boolean lowerCase) {
299
300 if ((values == null) || values.isEmpty()) {
301 return;
302 }
303
304 if (lowerCase) {
305 Map<Locale, String> lowerCaseValues = new HashMap<Locale, String>(
306 values.size());
307
308 for (Map.Entry<Locale, String> entry : values.entrySet()) {
309 String value = GetterUtil.getString(entry.getValue());
310
311 lowerCaseValues.put(entry.getKey(), value.toLowerCase());
312 }
313
314 values = lowerCaseValues;
315 }
316
317 Field field = new Field(name, values);
318
319 _fields.put(name, field);
320 }
321
322 public void addLocalizedText(String name, Map<Locale, String> values) {
323 if ((values == null) || values.isEmpty()) {
324 return;
325 }
326
327 Field field = new Field(name, values);
328
329 field.setTokenized(true);
330
331 _fields.put(name, field);
332 }
333
334
337 public void addModifiedDate() {
338 addModifiedDate(new Date());
339 }
340
341
344 public void addModifiedDate(Date modifiedDate) {
345 addDate(Field.MODIFIED, modifiedDate);
346 }
347
348 public void addNumber(String name, double value) {
349 addNumber(name, String.valueOf(value), Double.class);
350 }
351
352 public void addNumber(String name, Double value) {
353 addNumber(name, String.valueOf(value), Double.class);
354 }
355
356 public void addNumber(String name, double[] values) {
357 addNumber(name, ArrayUtil.toStringArray(values), Double.class);
358 }
359
360 public void addNumber(String name, Double[] values) {
361 addNumber(name, ArrayUtil.toStringArray(values), Double.class);
362 }
363
364 public void addNumber(String name, float value) {
365 addNumber(name, String.valueOf(value), Float.class);
366 }
367
368 public void addNumber(String name, Float value) {
369 addNumber(name, String.valueOf(value), Float.class);
370 }
371
372 public void addNumber(String name, float[] values) {
373 addNumber(name, ArrayUtil.toStringArray(values), Float.class);
374 }
375
376 public void addNumber(String name, Float[] values) {
377 addNumber(name, ArrayUtil.toStringArray(values), Float.class);
378 }
379
380 public void addNumber(String name, int value) {
381 addNumber(name, String.valueOf(value), Integer.class);
382 }
383
384 public void addNumber(String name, int[] values) {
385 addNumber(name, ArrayUtil.toStringArray(values), Integer.class);
386 }
387
388 public void addNumber(String name, Integer value) {
389 addNumber(name, String.valueOf(value), Integer.class);
390 }
391
392 public void addNumber(String name, Integer[] values) {
393 addNumber(name, ArrayUtil.toStringArray(values), Integer.class);
394 }
395
396 public void addNumber(String name, long value) {
397 addNumber(name, String.valueOf(value), Long.class);
398 }
399
400 public void addNumber(String name, Long value) {
401 addNumber(name, String.valueOf(value), Long.class);
402 }
403
404 public void addNumber(String name, long[] values) {
405 addNumber(name, ArrayUtil.toStringArray(values), Long.class);
406 }
407
408 public void addNumber(String name, Long[] values) {
409 addNumber(name, ArrayUtil.toStringArray(values), Long.class);
410 }
411
412 public void addNumber(String name, String value) {
413 addNumber(name, value, Long.class);
414 }
415
416 public void addNumber(
417 String name, String value, Class<? extends Number> clazz) {
418
419 if (Validator.isNotNull(value)) {
420 Field field = new Field(name, value);
421
422 field.setNumeric(true);
423 field.setNumericClass(clazz);
424
425 _fields.put(name, field);
426 }
427 }
428
429 public void addNumber(String name, String[] values) {
430 addNumber(name, values, Long.class);
431 }
432
433 public void addNumber(
434 String name, String[] values, Class<? extends Number> clazz) {
435
436 if (values == null) {
437 return;
438 }
439
440 Field field = new Field(name, values);
441
442 field.setNumeric(true);
443 field.setNumericClass(clazz);
444
445 _fields.put(name, field);
446 }
447
448 public void addText(String name, String value) {
449 if (Validator.isNull(value)) {
450 return;
451 }
452
453 Field field = new Field(name, value);
454
455 field.setTokenized(true);
456
457 _fields.put(name, field);
458
459 if (_sortableTextFields.contains(name)) {
460 String truncatedValue = value;
461
462 if (value.length() > _SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH) {
463 truncatedValue = value.substring(
464 0, _SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH);
465 }
466
467 addKeyword(getSortableFieldName(name), truncatedValue, true);
468 }
469 }
470
471 public void addText(String name, String[] values) {
472 if (values == null) {
473 return;
474 }
475
476 Field field = new Field(name, values);
477
478 field.setTokenized(true);
479
480 _fields.put(name, field);
481 }
482
483 public void addUID(String portletId, long field1) {
484 addUID(portletId, String.valueOf(field1));
485 }
486
487 public void addUID(String portletId, long field1, String field2) {
488 addUID(portletId, String.valueOf(field1), field2);
489 }
490
491 public void addUID(String portletId, Long field1) {
492 addUID(portletId, field1.longValue());
493 }
494
495 public void addUID(String portletId, Long field1, String field2) {
496 addUID(portletId, field1.longValue(), field2);
497 }
498
499 public void addUID(String portletId, String field1) {
500 addUID(portletId, field1, null);
501 }
502
503 public void addUID(String portletId, String field1, String field2) {
504 addUID(portletId, field1, field2, null);
505 }
506
507 public void addUID(
508 String portletId, String field1, String field2, String field3) {
509
510 addUID(portletId, field1, field2, field3, null);
511 }
512
513 public void addUID(
514 String portletId, String field1, String field2, String field3,
515 String field4) {
516
517 String uid = portletId + _UID_PORTLET + field1;
518
519 if (field2 != null) {
520 uid += _UID_FIELD + field2;
521 }
522
523 if (field3 != null) {
524 uid += _UID_FIELD + field3;
525 }
526
527 if (field4 != null) {
528 uid += _UID_FIELD + field4;
529 }
530
531 addKeyword(Field.UID, uid);
532 }
533
534 @Override
535 public Object clone() {
536 DocumentImpl documentImpl = new DocumentImpl();
537
538 documentImpl.setSortableTextFields(_sortableTextFields);
539
540 return documentImpl;
541 }
542
543 public String get(Locale locale, String name) {
544 if (locale == null) {
545 return get(name);
546 }
547
548 String localizedName = getLocalizedName(locale, name);
549
550 Field field = _fields.get(localizedName);
551
552 if (field == null) {
553 field = _fields.get(name);
554 }
555
556 if (field == null) {
557 return StringPool.BLANK;
558 }
559
560 return field.getValue();
561 }
562
563 public String get(Locale locale, String name, String defaultName) {
564 if (locale == null) {
565 return get(name, defaultName);
566 }
567
568 String localizedName = getLocalizedName(locale, name);
569
570 Field field = _fields.get(localizedName);
571
572 if (field == null) {
573 localizedName = getLocalizedName(locale, defaultName);
574
575 field = _fields.get(localizedName);
576 }
577
578 if (field == null) {
579 return StringPool.BLANK;
580 }
581
582 return field.getValue();
583 }
584
585 public String get(String name) {
586 Field field = _fields.get(name);
587
588 if (field == null) {
589 return StringPool.BLANK;
590 }
591
592 return field.getValue();
593 }
594
595 public String get(String name, String defaultName) {
596 Field field = _fields.get(name);
597
598 if (field == null) {
599 return get(defaultName);
600 }
601
602 return field.getValue();
603 }
604
605 public Date getDate(String name) throws ParseException {
606 DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat(
607 _INDEX_DATE_FORMAT_PATTERN);
608
609 return dateFormat.parse(get(name));
610 }
611
612 public Field getField(String name) {
613 return _fields.get(name);
614 }
615
616 public Map<String, Field> getFields() {
617 return _fields;
618 }
619
620 public String getPortletId() {
621 String uid = getUID();
622
623 int pos = uid.indexOf(_UID_PORTLET);
624
625 return uid.substring(0, pos);
626 }
627
628 public String getUID() {
629 Field field = _fields.get(Field.UID);
630
631 if (field == null) {
632 throw new RuntimeException("UID is not set");
633 }
634
635 return field.getValue();
636 }
637
638 public String[] getValues(String name) {
639 Field field = _fields.get(name);
640
641 if (field == null) {
642 return new String[] {StringPool.BLANK};
643 }
644
645 return field.getValues();
646 }
647
648 public boolean hasField(String name) {
649 if (_fields.containsKey(name)) {
650 return true;
651 }
652
653 return false;
654 }
655
656 public boolean isDocumentSortableTextField(String name) {
657 return _sortableTextFields.contains(name);
658 }
659
660 public void remove(String name) {
661 _fields.remove(name);
662 }
663
664 public void setFields(Map<String, Field> fields) {
665 _fields = fields;
666 }
667
668 public void setSortableTextFields(String[] sortableTextFields) {
669 _sortableTextFields = SetUtil.fromArray(sortableTextFields);
670 }
671
672 @Override
673 public String toString() {
674 StringBundler sb = new StringBundler();
675
676 sb.append(StringPool.OPEN_CURLY_BRACE);
677
678 boolean firstField = true;
679
680 for (Field field : _fields.values()) {
681 if (!firstField) {
682 sb.append(StringPool.COMMA);
683 sb.append(StringPool.SPACE);
684 }
685 else {
686 firstField = false;
687 }
688
689 sb.append(field.getName());
690 sb.append(StringPool.EQUAL);
691 sb.append(Arrays.toString(field.getValues()));
692 }
693
694 sb.append(StringPool.CLOSE_CURLY_BRACE);
695
696 return sb.toString();
697 }
698
699 protected void setSortableTextFields(Set<String> sortableTextFields) {
700 _sortableTextFields = sortableTextFields;
701 }
702
703 private static final String _INDEX_DATE_FORMAT_PATTERN = PropsUtil.get(
704 PropsKeys.INDEX_DATE_FORMAT_PATTERN);
705
706 private static final String _SORTABLE_TEXT_FIELD_SUFFIX = "sortable";
707
708 private static final int _SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH =
709 GetterUtil.getInteger(
710 PropsUtil.get(
711 PropsKeys.INDEX_SORTABLE_TEXT_FIELDS_TRUNCATED_LENGTH));
712
713 private static final String _UID_FIELD = "_FIELD_";
714
715 private static final String _UID_PORTLET = "_PORTLET_";
716
717 private static Format _dateFormat =
718 FastDateFormatFactoryUtil.getSimpleDateFormat(
719 _INDEX_DATE_FORMAT_PATTERN);
720 private static Set<String> _defaultSortableTextFields = SetUtil.fromArray(
721 PropsUtil.getArray(PropsKeys.INDEX_SORTABLE_TEXT_FIELDS));
722
723 private Map<String, Field> _fields = new HashMap<String, Field>();
724 private Set<String> _sortableTextFields = _defaultSortableTextFields;
725
726 }