diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 262105ae6..b94d4d812 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -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 rosterStore; private final Map groups = new ConcurrentHashMap<>(); /** @@ -168,7 +169,7 @@ public final class Roster extends Manager { private final Map> 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 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 addedEntries, Collection updatedEntries, - Collection unchangedEntries, RosterPacket.Item item, RosterEntry entry) { + Collection 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 validItems = new ArrayList<>(); + ArrayList 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 storedItems = rosterStore.getEntries(); + List 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); } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java index a75a024ac..82419f5e3 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java @@ -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; } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterItemRecord.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterItemRecord.java index 6349972c4..7765c90a8 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterItemRecord.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterItemRecord.java @@ -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 getGroupNames(); + + RosterPacket.ItemType getItemType(); } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java index 430fa3434..197ff5678 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java @@ -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 getGroupNames() { return Collections.unmodifiableSet(groupNames); } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java index 3dd4fde6a..cf16fb2b8 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/DirectoryRosterStore.java @@ -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 { private final File fileDir; @@ -182,7 +183,7 @@ public final class DirectoryRosterStore implements RosterStore { @Override public void resetStore() { - resetEntries(Collections.emptyList(), ""); + resetEntries(Collections.emptyList(), ""); } @SuppressWarnings("DefaultCharset") diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java index e7db278d9..6a66dc35f 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/rosterstore/RosterStore.java @@ -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 { /** * This method returns a list of all roster items contained in this store. If there was an error while loading the store, then null is returned. * - * @return List of {@link org.jivesoftware.smack.roster.RosterEntry} or null. + * @return List of {@link RosterItemRecord} or null. */ - List getEntries(); + List 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 items, String version); + boolean resetEntries(Collection items, String version); /** * Removes an entry from the store. diff --git a/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterVersioningTest.java b/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterVersioningTest.java index f3eeb3b23..f6ae54e02 100644 --- a/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterVersioningTest.java +++ b/smack-im/src/test/java/org/jivesoftware/smack/roster/RosterVersioningTest.java @@ -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();