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