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