All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.intelie.live.plugins.messenger.search.SearchableMessageHandler Maven / Gradle / Ivy

The newest version!
package net.intelie.live.plugins.messenger.search;

import net.intelie.live.*;
import net.intelie.live.model.User;
import net.intelie.live.plugins.messenger.chat.ChatManager;
import net.intelie.live.plugins.messenger.chat.RoomState;
import net.intelie.live.plugins.messenger.data.RoomData;
import net.intelie.live.plugins.messenger.data.UserMessage;
import net.intelie.live.plugins.messenger.search.document.*;
import net.intelie.live.queries.AllUsers;
import net.intelie.pipes.Property;
import net.intelie.pipes.filters.Filter;
import net.intelie.pipes.filters.OrFilter;
import net.intelie.pipes.filters.TermFilter;
import net.intelie.pipes.types.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

import static net.intelie.live.plugins.messenger.chat.EventUtils.fromEvent;
import static net.intelie.live.plugins.messenger.chat.EventUtils.toEvent;
import static net.intelie.live.plugins.messenger.chat.MessagesManager.MESSAGE;
import static net.intelie.live.plugins.messenger.search.SearchableFields.*;

public class SearchableMessageHandler implements SearchableEventHandler {

    /// __message type fields to be indexed
    static final String ROOM = "room";
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchableMessageHandler.class);
    private final Live live;
    private final ChatManager chatManager;

    public SearchableMessageHandler(Live live, ChatManager chatManager) {
        this.live = live;
        this.chatManager = chatManager;
    }

    private static User resolveUser(EntityContext context, Integer userId) {
        return context.inTransaction(() -> context.findOneOf(new AllUsers().byIds(Collections.singleton(userId))));
    }

    @Override
    public String searchableName() {
        return MESSAGE;
    }

    @Override
    public Set searchableFields() {
        Set retSet = new HashSet<>();
        retSet.add(EVENT_TYPE);
        retSet.add(CREATED_BY);
        retSet.add(ROOM);
        return retSet;
    }

    @Override
    public Query createQuery(Long lastTimestamp) {
        long span = lastTimestamp != null ? lastTimestamp : 0;
        return new net.intelie.live.Query(MESSAGE)
                .span("from ts " + span)
                .follow()
                .description("fulltext index query");
    }

    @Override
    public List eventToSearchable(String uid, Map event) {
        List document = new ArrayList<>();
        String eventType = Type.STRING.cast(event.get(Event.TYPE));
        String eventSrc = Type.STRING.cast(event.get(Event.SRC));
        Double eventCreatedAt = Type.NUMBER.cast(event.get(CREATED_AT));
        UserMessage userMessage = LiveJson.fromJson(LiveJson.toJsonTree(event), UserMessage.class);
        if (userMessage == null || userMessage.getMessage() == null) {
            return null;
        }

        RoomState roomState;
        User userData;
        try {
            roomState = chatManager.getRoom(userMessage.getRoom().getId());
            userData = resolveUser(live.data().getContext(), userMessage.getAuthor().getId());
        } catch (Exception ex) {
            return null;
        }

        document.add(new StringSearchField(UID, uid, true));
        document.add(new StringSearchField(EVENT_TYPE, eventType, true));
        document.add(new StringSearchField(EVENT_SRC, eventSrc, true));
        document.add(new StringSearchField(EVENT_UID, userMessage.getUid(), true));
        if (userData != null) {
            document.add(new TextSearchField(CREATED_BY, userData.getDisplayName(), false));
            document.add(new TextSearchField(CREATED_BY, userData.getUsername(), false));
        }
        document.add(new TextSearchField(ROOM, roomState.getName(), false));
        document.add(new LongPointSearchField(CREATED_AT, eventCreatedAt.longValue()));
        document.add(new NumericDocValuesField(CREATED_AT, eventCreatedAt.longValue()));
        document.add(new TextSearchField(DEFAULT_FIELD, userMessage.getMessage(), false));
        return document;
    }

    @Override
    public List> loadFoundEvents(UserDef user, List foundDocs) throws Exception {
        Property uidProperty = live.pipes().compiler().getContext().property("uid");
        Set visibleRooms = chatManager.roomsVisibleToUser(user.getId(), user.isSuperuser()).stream().map(RoomData::getId).collect(Collectors.toSet());
        List filters = foundDocs.stream().filter(doc -> MESSAGE.equals(doc.get(EVENT_TYPE))).map(doc -> TermFilter.literal(uidProperty, doc.get(EVENT_UID))).collect(Collectors.toList());
        Filter filter = new OrFilter(filters);
        List> events = new ArrayList<>();
        try (EventIterator it = loadEvents(MESSAGE, filter)) {
            while (it.moveNext()) {
                Map event = new LinkedHashMap<>(it.current());
                RoomData eventRoomData = fromEvent(event.get(ROOM), RoomData.class);
                if (!visibleRooms.contains(eventRoomData.getId())) {
                    continue;
                }
                try {
                    RoomState roomState;
                    roomState = chatManager.getRoom(eventRoomData.getId());
                    RoomData roomData = new RoomData(eventRoomData.getId(), roomState.getName(), null, null, null, null);
                    event.put(ROOM, toEvent(roomData));
                    events.add(event);
                } catch (Exception ex) {
                    LOGGER.info("Error loading room id -> {}", eventRoomData.getId());
                }
            }
            return events;
        }
    }

    private EventIterator loadEvents(String eventType, Filter filter) throws Exception {
        return live.engine().getMainStorage().query(new StorageQuery(eventType).withWhere(filter), 0, Long.MAX_VALUE, new StorageQueryOptions(false, false));
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy