package ru.hflabs.rcd.lucene.binder; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableSet; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.TextField; import org.apache.lucene.index.IndexableField; import org.apache.lucene.index.Term; import org.springframework.util.StringUtils; import ru.hflabs.rcd.index.IndexedClass; import ru.hflabs.rcd.lucene.IndexBinderTransformer; import ru.hflabs.rcd.model.Identifying; import ru.hflabs.rcd.service.ISingleClassObserver; import ru.hflabs.util.lucene.LuceneUtil; import java.util.Arrays; import java.util.Collection; import static ru.hflabs.util.lucene.LuceneUtil.KRYO_OBJECT_TO_BYTE_CONVERTER; /** * Класс <class>LuceneBinderTransformerTemplate</class> реализует базовый сервис преобразования поисковой сущности в сущность API * * @author Nazin Alexander */ public abstract class LuceneBinderTransformerTemplate<E extends Identifying> implements IndexBinderTransformer<E, String>, ISingleClassObserver<E> { /** Статус сохранения поисковых полей */ public static final Field.Store FIELD_STORED = Field.Store.NO; /** Описание индексации */ private final IndexedClass<E> indexedClass; public LuceneBinderTransformerTemplate(IndexedClass<E> indexedClass) { this.indexedClass = indexedClass; } @Override public IndexedClass<E> retrieveIndexedClass() { return indexedClass; } @Override public Class<E> retrieveTargetClass() { return indexedClass.getIndexedClass(); } @Override public Term getPrimaryKey(E essence) { return new Term(E.PRIMARY_KEY, essence.getId()); } @Override public String getPrimaryKey(Document document) { return document.get(E.PRIMARY_KEY); } @Override public E convert(Document source) { return LuceneUtil.byteToObject(retrieveTargetClass(), source.getBinaryValue(OBJECT_FIELD), KRYO_OBJECT_TO_BYTE_CONVERTER); } /** * Создает поле поиска по умолчанию * * @param values коллекция значений для поиска * @return Возвращает поле поиска поумолчанию */ protected static IndexableField createDefaultSearchField(Iterable<IndexableField> values) { ImmutableSet.Builder<String> defaultValues = ImmutableSet.builder(); for (IndexableField field : values) { String value = field.stringValue(); if (value != null) { Collection<String> worlds = Collections2.filter( Arrays.asList(LuceneUtil.SPACE_REGEXP.split(value)), new Predicate<String>() { @Override public boolean apply(String o) { return StringUtils.hasText(o); } } ); defaultValues.addAll(worlds); } } return new TextField(DEFAULT_SEARCH_FIELD, StringUtils.collectionToDelimitedString(defaultValues.build(), " "), FIELD_STORED); } /** * Выполняет подготовку сущности к сериализации - удаление транзитивных полей и т.д. * * @param target целевая сущность * @return Возвращает подготовленную сущность */ protected abstract E prepareToSerialize(E target); }