net.dv8tion.jda.core.MessageHistory.java Source code

Java tutorial

Introduction

Here is the source code for net.dv8tion.jda.core.MessageHistory.java

Source

/*
 *     Copyright 2015-2016 Austin Keener & Michael Ritter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package net.dv8tion.jda.core;

import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.entities.MessageChannel;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.impl.JDAImpl;
import net.dv8tion.jda.core.events.Event;
import net.dv8tion.jda.core.events.message.MessageDeleteEvent;
import net.dv8tion.jda.core.events.message.MessageUpdateEvent;
import net.dv8tion.jda.core.exceptions.PermissionException;
import net.dv8tion.jda.core.entities.EntityBuilder;
import net.dv8tion.jda.core.requests.Request;
import net.dv8tion.jda.core.requests.Response;
import net.dv8tion.jda.core.requests.RestAction;
import net.dv8tion.jda.core.requests.Route;
import org.apache.commons.collections4.map.ListOrderedMap;
import org.json.JSONArray;

import java.util.*;

public class MessageHistory implements net.dv8tion.jda.core.hooks.EventListener {
    protected final JDAImpl api;
    protected final MessageChannel channel;

    protected ListOrderedMap<String, Message> history = new ListOrderedMap<>();
    protected String markerId;

    public MessageHistory(MessageChannel channel) {
        this.api = (JDAImpl) channel.getJDA();
        this.channel = channel;
        if (channel instanceof TextChannel && !((TextChannel) channel).getGuild().getMember(api.getSelfUser())
                .hasPermission(Permission.MESSAGE_HISTORY))
            throw new PermissionException(Permission.MESSAGE_HISTORY);
    }

    /**
     * Returns the {@link net.dv8tion.jda.core.entities.MessageChannel MessageChannel} that this MessageHistory
     * is related to.
     *
     * @return
     *      The MessageChannel of this history.
     */
    public MessageChannel getChannel() {
        return channel;
    }

    public synchronized RestAction<List<Message>> retrievePast(int amount) {
        if (amount > 100 || amount < 0)
            throw new IllegalArgumentException(
                    "Message retrieval limit is between 1 and 100 messages. No more, no less. Limit provided: "
                            + amount);

        Route.CompiledRoute route;
        if (history.isEmpty())
            route = Route.Messages.GET_MESSAGE_HISTORY.compile(channel.getId(), Integer.toString(amount));
        else
            route = Route.Messages.GET_MESSAGE_HISTORY_BEFORE.compile(channel.getId(), Integer.toString(amount),
                    history.lastKey());
        return new RestAction<List<Message>>(api, route, null) {
            @Override
            protected void handleResponse(Response response, Request request) {
                if (!response.isOk())
                    request.onFailure(response);

                EntityBuilder builder = EntityBuilder.get(api);
                LinkedList<Message> msgs = new LinkedList<>();
                JSONArray historyJson = response.getArray();

                for (int i = 0; i < historyJson.length(); i++)
                    msgs.add(builder.createMessage(historyJson.getJSONObject(i)));

                if (history.isEmpty())

                    msgs.forEach(msg -> history.put(msg.getId(), msg));
                request.onSuccess(msgs);
            }
        };
    }

    public RestAction<List<Message>> retrieveFuture(int amount) {
        if (amount > 100 || amount < 0)
            throw new IllegalArgumentException(
                    "Message retrieval limit is between 1 and 100 messages. No more, no less. Limit provided: "
                            + amount);

        if (history.isEmpty())
            throw new IllegalStateException(
                    "No messageId  is stored to use as the marker between the future and past."
                            + "Either use MessageHistory(MessageChannel, String) or make a call to retrievePast(int) first.");

        Route.CompiledRoute route = Route.Messages.GET_MESSAGE_HISTORY_AFTER.compile(channel.getId(),
                Integer.toString(amount), history.firstKey());
        return new RestAction<List<Message>>(api, route, null) {
            @Override
            protected void handleResponse(Response response, Request request) {
                if (!response.isOk())
                    request.onFailure(response);

                EntityBuilder builder = EntityBuilder.get(api);
                LinkedList<Message> msgs = new LinkedList<>();
                JSONArray historyJson = response.getArray();

                for (int i = 0; i < historyJson.length(); i++)
                    msgs.add(builder.createMessage(historyJson.getJSONObject(i)));

                for (Iterator<Message> it = msgs.descendingIterator(); it.hasNext();) {
                    Message m = it.next();
                    history.put(0, m.getId(), m);
                }

                request.onSuccess(msgs);
            }
        };
    }

    public List<Message> getCachedHistory() {
        return Collections.unmodifiableList(new ArrayList<>(history.values()));
    }

    public Message getMessageById(String id) {
        return history.get(id);
    }

    public Message informUpdate(Message msg) {
        if (msg.getChannel().equals(channel) && history.containsKey(msg.getId()))
            return history.put(msg.getId(), msg);

        return null;
    }

    public Message informDeletion(Message msg) {
        if (msg.getChannel().equals(channel))
            return informDeletion(msg.getId());

        return null;
    }

    public Message informDeletion(String id) {
        if (id == null)
            throw new NullPointerException("Provided message id was null!");
        return history.remove(id);
    }

    @Override
    public void onEvent(Event event) {
        if (event instanceof MessageUpdateEvent) {
            informUpdate(((MessageUpdateEvent) event).getMessage());
        } else if (event instanceof MessageDeleteEvent) {
            MessageDeleteEvent mEvent = (MessageDeleteEvent) event;
            if (mEvent.getChannel().equals(channel)) {
                history.remove(mEvent.getMessageId());
            }
        }
    }

    public static RestAction<MessageHistory> getHistoryAround(MessageChannel channel, Message message, int limit) {
        if (!message.getChannel().equals(channel))
            throw new IllegalArgumentException("The provided Message is not from the MessageChannel!");

        return getHistoryAround(channel, message.getId(), limit);
    }

    public static RestAction<MessageHistory> getHistoryAround(MessageChannel channel, final String markerMessageId,
            int limit) {
        if (markerMessageId == null)
            throw new IllegalArgumentException("Provided markedMessageId cannot be null!");

        if (limit > 100 || limit < 1)
            throw new IllegalArgumentException(
                    "Provided limit was out of bounds. Minimum: 1, Max: 100. Provided: " + limit);

        Route.CompiledRoute route = Route.Messages.GET_MESSAGE_HISTORY_AROUND.compile(channel.getId(),
                Integer.toString(limit), markerMessageId);
        return new RestAction<MessageHistory>(channel.getJDA(), route, null) {
            @Override
            protected void handleResponse(Response response, Request request) {
                if (!response.isOk())
                    request.onFailure(response);

                MessageHistory mHistory = new MessageHistory(channel);
                mHistory.markerId = markerMessageId;

                EntityBuilder builder = EntityBuilder.get(api);
                LinkedList<Message> msgs = new LinkedList<>();
                JSONArray historyJson = response.getArray();

                for (int i = 0; i < historyJson.length(); i++)
                    msgs.add(builder.createMessage(historyJson.getJSONObject(i)));

                msgs.forEach(msg -> mHistory.history.put(msg.getId(), msg));
                request.onSuccess(mHistory);
            }
        };
    }
}