1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-14 00:02:05 +01:00
This commit is contained in:
Paul Schaub 2019-07-24 16:29:58 +02:00
parent f170438b1e
commit 4975f4a28f
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
7 changed files with 69 additions and 27 deletions

View file

@ -63,6 +63,7 @@ import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.roster.packet.RosterVer;
import org.jivesoftware.smack.roster.packet.SubscriptionPreApproval;
import org.jivesoftware.smack.roster.rosterstore.DirectoryRosterStore;
import org.jivesoftware.smack.roster.rosterstore.RosterStore;
import org.jivesoftware.smack.util.ExceptionCallback;
import org.jivesoftware.smack.util.Objects;
@ -148,7 +149,7 @@ public final class Roster extends Manager {
private static int defaultNonRosterPresenceMapMaxSize = INITIAL_DEFAULT_NON_ROSTER_PRESENCE_MAP_SIZE;
private RosterStore rosterStore;
private RosterStore<RosterItemRecord> rosterStore;
private final Map<String, RosterGroup> groups = new ConcurrentHashMap<>();
/**
@ -168,7 +169,7 @@ public final class Roster extends Manager {
private final Map<BareJid, Map<Resourcepart, Presence>> presenceMap = new ConcurrentHashMap<>();
/**
* Like {@link presenceMap} but for presences of entities not in our Roster.
* Like presenceMap but for presences of entities not in our Roster.
*/
// TODO Ideally we want here to use a LRU cache like Map which will evict all superfluous items
// if their maximum size is lowered below the current item count. LruCache does not provide
@ -182,7 +183,7 @@ public final class Roster extends Manager {
private final Set<RosterLoadedListener> rosterLoadedListeners = new LinkedHashSet<>();
/**
* Mutually exclude roster listener invocation and changing the {@link entries} map. Also used
* Mutually exclude roster listener invocation and changing the entries map. Also used
* to synchronize access to either the roster listeners or the entries map.
*/
private final Object rosterListenersAndEntriesLock = new Object();
@ -491,6 +492,7 @@ public final class Roster extends Manager {
* @return true if the roster reload was initiated, false otherwise.
* @since 4.1
*/
@SuppressWarnings({"unchecked", "rawtype"})
public boolean setRosterStore(RosterStore rosterStore) {
this.rosterStore = rosterStore;
try {
@ -1344,7 +1346,7 @@ public final class Roster extends Manager {
}
private void addUpdateEntry(Collection<Jid> addedEntries, Collection<Jid> updatedEntries,
Collection<Jid> unchangedEntries, RosterPacket.Item item, RosterEntry entry) {
Collection<Jid> unchangedEntries, RosterItemRecord item, RosterEntry entry) {
RosterEntry oldEntry;
synchronized (rosterListenersAndEntriesLock) {
oldEntry = entries.put(item.getJid(), entry);
@ -1691,14 +1693,14 @@ public final class Roster extends Manager {
RosterPacket rosterPacket = (RosterPacket) packet;
// Ignore items without valid subscription type
ArrayList<Item> validItems = new ArrayList<>();
ArrayList<RosterItemRecord> validItems = new ArrayList<>();
for (RosterPacket.Item item : rosterPacket.getRosterItems()) {
if (hasValidSubscriptionType(item)) {
validItems.add(item);
}
}
for (RosterPacket.Item item : validItems) {
for (RosterItemRecord item : validItems) {
RosterEntry entry = new RosterEntry(item, Roster.this, connection);
addUpdateEntry(addedEntries, updatedEntries, unchangedEntries, item, entry);
}
@ -1727,7 +1729,7 @@ public final class Roster extends Manager {
// means that rosterver was used and the roster hasn't changed (much) since the
// version we presented the server. So we simply load the roster from the store and
// await possible further roster pushes.
List<RosterPacket.Item> storedItems = rosterStore.getEntries();
List<RosterItemRecord> storedItems = rosterStore.getEntries();
if (storedItems == null) {
// The roster store was corrupted. Reset the store and reload the roster without using a roster version.
rosterStore.resetStore();
@ -1741,7 +1743,7 @@ public final class Roster extends Manager {
}
return;
}
for (RosterPacket.Item item : storedItems) {
for (RosterItemRecord item : storedItems) {
RosterEntry entry = new RosterEntry(item, Roster.this, connection);
addUpdateEntry(addedEntries, updatedEntries, unchangedEntries, item, entry);
}

View file

@ -45,7 +45,7 @@ import org.jxmpp.jid.BareJid;
*/
public final class RosterEntry extends Manager {
private RosterPacket.Item item;
private RosterItemRecord item;
private final Roster roster;
/**
@ -55,7 +55,7 @@ public final class RosterEntry extends Manager {
* @param roster The Roster managing this entry.
* @param connection a connection to the XMPP server.
*/
RosterEntry(RosterPacket.Item item, Roster roster, XMPPConnection connection) {
RosterEntry(RosterItemRecord item, Roster roster, XMPPConnection connection) {
super(connection);
this.item = item;
this.roster = roster;
@ -114,7 +114,7 @@ public final class RosterEntry extends Manager {
connection().createStanzaCollectorAndSend(packet).nextResultOrThrow();
// We have received a result response to the IQ set, the name was successfully changed
item.setName(name);
this.item = toRosterItem(this, name);
}
/**
@ -122,7 +122,7 @@ public final class RosterEntry extends Manager {
*
* @param item new item
*/
void updateItem(RosterPacket.Item item) {
void updateItem(RosterItemRecord item) {
assert (item != null);
this.item = item;
}

View file

@ -1,4 +1,38 @@
/**
*
* Copyright 2019 Paul Schaub.
*
* 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 org.jivesoftware.smack.roster;
import java.util.Set;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jxmpp.jid.BareJid;
public interface RosterItemRecord {
BareJid getJid();
String getName();
boolean isSubscriptionPending();
boolean isApproved();
Set<String> getGroupNames();
RosterPacket.ItemType getItemType();
}

View file

@ -27,6 +27,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.roster.RosterItemRecord;
import org.jivesoftware.smack.util.EqualsUtil;
import org.jivesoftware.smack.util.HashCode;
import org.jivesoftware.smack.util.Objects;
@ -112,7 +113,7 @@ public final class RosterPacket extends IQ {
* the groups the roster item belongs to.
*/
// TODO Make this class immutable.
public static final class Item implements NamedElement {
public static final class Item implements NamedElement, RosterItemRecord {
/**
* The constant value "{@value}".
@ -179,6 +180,7 @@ public final class RosterPacket extends IQ {
*
* @return the JID.
*/
@Override
public BareJid getJid() {
return jid;
}
@ -188,6 +190,7 @@ public final class RosterPacket extends IQ {
*
* @return the user's name.
*/
@Override
public String getName() {
return name;
}
@ -206,6 +209,7 @@ public final class RosterPacket extends IQ {
*
* @return the roster item type.
*/
@Override
public ItemType getItemType() {
return itemType;
}
@ -223,6 +227,7 @@ public final class RosterPacket extends IQ {
this.subscriptionPending = subscriptionPending;
}
@Override
public boolean isSubscriptionPending() {
return subscriptionPending;
}
@ -232,6 +237,7 @@ public final class RosterPacket extends IQ {
*
* @return the pre-approval state.
*/
@Override
public boolean isApproved() {
return approved;
}
@ -251,6 +257,7 @@ public final class RosterPacket extends IQ {
*
* @return an unmodifiable set of the group names.
*/
@Override
public Set<String> getGroupNames() {
return Collections.unmodifiableSet(groupNames);
}

View file

@ -29,6 +29,7 @@ import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.packet.RosterPacket.Item;
import org.jivesoftware.smack.roster.provider.RosterPacketProvider;
import org.jivesoftware.smack.util.FileUtils;
@ -47,7 +48,7 @@ import org.jxmpp.jid.Jid;
* @author Fabian Schuetz
* @author Florian Schmaus
*/
public final class DirectoryRosterStore implements RosterStore {
public final class DirectoryRosterStore implements RosterStore<RosterPacket.Item> {
private final File fileDir;
@ -182,7 +183,7 @@ public final class DirectoryRosterStore implements RosterStore {
@Override
public void resetStore() {
resetEntries(Collections.<Item>emptyList(), "");
resetEntries(Collections.emptyList(), "");
}
@SuppressWarnings("DefaultCharset")

View file

@ -19,7 +19,7 @@ package org.jivesoftware.smack.roster.rosterstore;
import java.util.Collection;
import java.util.List;
import org.jivesoftware.smack.roster.packet.RosterPacket;
import org.jivesoftware.smack.roster.RosterItemRecord;
import org.jxmpp.jid.Jid;
@ -28,22 +28,22 @@ import org.jxmpp.jid.Jid;
* roster versioning as per RFC 6121.
*/
public interface RosterStore {
public interface RosterStore<I extends RosterItemRecord> {
/**
* This method returns a list of all roster items contained in this store. If there was an error while loading the store, then <code>null</code> is returned.
*
* @return List of {@link org.jivesoftware.smack.roster.RosterEntry} or <code>null</code>.
* @return List of {@link RosterItemRecord} or <code>null</code>.
*/
List<RosterPacket.Item> getEntries();
List<I> getEntries();
/**
* This method returns the roster item in this store for the given JID.
*
* @param bareJid The bare JID of the RosterEntry
* @return The {@link org.jivesoftware.smack.roster.RosterEntry} which belongs to that user
* @return The {@link RosterItemRecord} which belongs to that user
*/
RosterPacket.Item getEntry(Jid bareJid);
I getEntry(Jid bareJid);
/**
* This method returns the version number as specified by the "ver" attribute
@ -60,7 +60,7 @@ public interface RosterStore {
* @param version the new roster version
* @return True if successful
*/
boolean addEntry(RosterPacket.Item item, String version);
boolean addEntry(I item, String version);
/**
* This method updates the store so that it contains only the given entries.
@ -69,7 +69,7 @@ public interface RosterStore {
* @param version the new roster version
* @return True if successful
*/
boolean resetEntries(Collection<RosterPacket.Item> items, String version);
boolean resetEntries(Collection<I> items, String version);
/**
* Removes an entry from the store.

View file

@ -60,6 +60,7 @@ public class RosterVersioningTest {
private DummyConnection connection;
private Roster roster;
private DirectoryRosterStore store;
private TestRosterListener rosterListener;
@Rule
@ -67,7 +68,7 @@ public class RosterVersioningTest {
@Before
public void setUp() throws Exception {
DirectoryRosterStore store = DirectoryRosterStore.init(tmpFolder.newFolder("store"));
store = DirectoryRosterStore.init(tmpFolder.newFolder("store"));
populateStore(store);
connection = new DummyConnection();
@ -163,7 +164,6 @@ public class RosterVersioningTest {
assertNotNull("Roster contains vaglaf entry", entry);
assertEquals("vaglaf entry in roster equals the sent entry", vaglafItem, RosterEntry.toRosterItem(entry));
RosterStore store = roster.getRosterStore();
assertEquals("Size of store", 1, store.getEntries().size());
Item item = store.getEntry(vaglafItem.getJid());
assertNotNull("Store contains vaglaf entry", item);
@ -179,8 +179,6 @@ public class RosterVersioningTest {
answerWithEmptyRosterResult();
rosterListener.waitAndReset();
RosterStore store = roster.getRosterStore();
// Simulate a roster push adding vaglaf
{
RosterPacket rosterPush = new RosterPacket();