aboutsummaryrefslogtreecommitdiffstats
path: root/src/de/thedevstack/xmpp/mamloader/MamLoadClient.java
blob: 66e8969902f422e55fe69f78c9f052140d0f5deb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package de.thedevstack.xmpp.mamloader;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.SmackException.NotLoggedInException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.forward.packet.Forwarded;
import org.jivesoftware.smackx.mam.MamManager;
import org.jivesoftware.smackx.mam.MamManager.MamQueryResult;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;

public class MamLoadClient {
	private static final int LIMIT_PER_REQUEST = 50;
	private AbstractXMPPConnection connection;
	private MamManager mamManager;
	private boolean debug;
	
	public MamLoadClient(boolean debug) {
		this.debug = debug;
	}
	
	public void connectAndLogin(String username, String password) throws SmackException, IOException, XMPPException, InterruptedException {
		BareJid userJid = JidCreate.bareFrom(username);
		this.connectAndLogin(userJid.getLocalpartOrThrow().toString(), password, userJid.getDomain().toString());
	}

	private void connectAndLogin(String username, String password, String host) throws SmackException, IOException, XMPPException, InterruptedException {
		XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
				  .setUsernameAndPassword(username, password)
				  .setXmppDomain(host)
				  .setHost(host)
				  .setDebuggerEnabled(this.debug)
				  //.setCustomSSLContext(SSLHelper.createNaiveSSLContext())
				  .setResource("MAMLoader_" + UUID.randomUUID())
				  .setSendPresence(false)
				  .build();
		connection = new XMPPTCPConnection(config);
		connection.connect();
		connection.login();

		mamManager = MamManager.getInstanceFor(connection);
	}
	
	public void disconnect() {
		this.connection.disconnect();
	}
	
	public List<Forwarded> loadHistory(String jid) throws XmppStringprepException, NoResponseException, XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
		return this.loadHistory(jid, null, null);
	}
	
	public List<Forwarded> loadHistory(String jid, Date start) throws XmppStringprepException, NoResponseException, XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
		return this.loadHistory(jid, start, null);
	}
	
	public List<Forwarded> loadHistory(String jid, Date start, Date end) throws XmppStringprepException, NoResponseException, XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
		List<Forwarded> allMessages = new ArrayList<>();
		if (mamManager.isSupported()) {
			Jid withJid = JidCreate.bareFrom(jid);
			MamQueryResult archive = mamManager.queryArchive(null, start, end, withJid, null);
			allMessages.addAll(archive.forwardedMessages);
			while (!archive.mamFin.isComplete()) {
				archive = mamManager.pageNext(archive, LIMIT_PER_REQUEST);
				allMessages.addAll(archive.forwardedMessages);
			}
			
			allMessages = this.filterAndSort(allMessages);
		}
		
		return allMessages;
	}
	
	public List<Forwarded> loadHistory(String jid, int limit) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotLoggedInException, XmppStringprepException {
		List<Forwarded> allMessages = new ArrayList<>();
		if (mamManager.isSupported()) {
			Jid withJid = JidCreate.bareFrom(jid);
			MamQueryResult archive = mamManager.mostRecentPage(withJid, LIMIT_PER_REQUEST);

			allMessages.addAll(archive.forwardedMessages);
			while (!archive.mamFin.isComplete() && limit > allMessages.size()) {
				int requestLimit = limit - allMessages.size();
				archive = mamManager.pagePrevious(archive, (requestLimit < LIMIT_PER_REQUEST ? requestLimit : LIMIT_PER_REQUEST));
				allMessages.addAll(archive.forwardedMessages);
			}
			
			allMessages = this.filterAndSort(allMessages);
		}
		
		return allMessages;
	}
	
	private List<Forwarded> filterAndSort(List<Forwarded> messages) {
		return messages.stream()
				.filter(forwarded -> forwarded.getForwardedStanza() instanceof Message
						&& ((Message)forwarded.getForwardedStanza()).getBody() != null)
				.sorted(new Comparator<Forwarded>() {
					@Override
					public int compare(Forwarded o1, Forwarded o2) {
						return o1.getDelayInformation().getStamp().compareTo(o2.getDelayInformation().getStamp());
					}
				})
				.collect(Collectors.toList());
	}
}