org.jxmpp.jid.BareJid Java Examples

The following examples show how to use org.jxmpp.jid.BareJid. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Roster.java    From Smack with Apache License 2.0 6 votes vote down vote up
/**
 * Returns a List of Presence objects for all of a user's current presences if no presence information is available,
 * such as when you are not subscribed to the user's presence updates.
 *
 * @param bareJid an XMPP ID, e.g. [email protected].
 * @return a List of Presence objects for all the user's current presences, or an unavailable presence if no
 *         presence information is available.
 */
public List<Presence> getAllPresences(BareJid bareJid) {
    Map<Resourcepart, Presence> userPresences = getPresencesInternal(bareJid);
    List<Presence> res;
    if (userPresences == null) {
        // Create an unavailable presence if none was found
        Presence unavailable = synthesizeUnvailablePresence(bareJid);
        res = new ArrayList<>(Arrays.asList(unavailable));
    } else {
        res = new ArrayList<>(userPresences.values().size());
        for (Presence presence : userPresences.values()) {
            res.add(presence);
        }
    }
    return res;
}
 
Example #2
Source File: RosterTest.java    From Smack with Apache License 2.0 6 votes vote down vote up
/**
 * Tests that roster pushes with invalid from are ignored.
 * @throws XmppStringprepException if the provided string is invalid.
 *
 * @see <a href="http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push">RFC 6121, Section 2.1.6</a>
 */
@Test
public void testIgnoreInvalidFrom() throws XmppStringprepException {
    final BareJid spammerJid = JidCreate.entityBareFrom("[email protected]");
    RosterPacket packet = new RosterPacket();
    packet.setType(Type.set);
    packet.setTo(connection.getUser());
    packet.setFrom(JidCreate.entityBareFrom("[email protected]"));
    packet.addRosterItem(new Item(spammerJid, "Cool products!"));

    final String requestId = packet.getStanzaId();
    // Simulate receiving the roster push
    connection.processStanza(packet);

    // Smack should reply with an error IQ
    ErrorIQ errorIQ = connection.getSentPacket();
    assertEquals(requestId, errorIQ.getStanzaId());
    assertEquals(Condition.service_unavailable, errorIQ.getError().getCondition());

    assertNull("Contact was added to roster", Roster.getInstanceFor(connection).getEntry(spammerJid));
}
 
Example #3
Source File: Roster.java    From Smack with Apache License 2.0 6 votes vote down vote up
/**
 * Retrieve the user presences (a map from resource to {@link Presence}) for a given XMPP entity represented by their bare JID.
 *
 * @param entity the entity
 * @return the user presences
 */
private synchronized Map<Resourcepart, Presence> getOrCreatePresencesInternal(BareJid entity) {
    Map<Resourcepart, Presence> entityPresences = getPresencesInternal(entity);
    if (entityPresences == null) {
        if (contains(entity)) {
            entityPresences = new ConcurrentHashMap<>();
            presenceMap.put(entity, entityPresences);
        }
        else {
            LruCache<Resourcepart, Presence> nonRosterEntityPresences = new LruCache<>(32);
            nonRosterPresenceMap.put(entity, nonRosterEntityPresences);
            entityPresences = nonRosterEntityPresences;
        }
    }
    return entityPresences;
}
 
Example #4
Source File: NotificationPlugin.java    From Spark with Apache License 2.0 6 votes vote down vote up
private void registerListener() {
    preferences = SettingsManager.getLocalPreferences();

    // Iterate through all online users and add them to the list.
    ContactList contactList = SparkManager.getWorkspace().getContactList();
    for (ContactGroup contactGroup : contactList.getContactGroups()) {
        for (ContactItem item : contactGroup.getContactItems()) {
            if (item != null && item.getJid() != null && item.getPresence().isAvailable()) {
                BareJid bareJID = item.getJid().asBareJid();
                onlineUsers.add(bareJID);
            }
        }
    }

    // Add Presence Listener
    SparkManager.getConnection().addAsyncStanzaListener(this, new StanzaTypeFilter(Presence.class));
}
 
Example #5
Source File: NotificationAlertUI.java    From Spark with Apache License 2.0 6 votes vote down vote up
public NotificationAlertUI(BareJid jid, boolean available, Presence presence) {
    setLayout(new GridBagLayout());

    this.available = available;
    this.jid = jid;

    vcard = SparkManager.getVCardManager().getVCardFromMemory(jid);

    final Icon presenceIcon = PresenceManager.getIconFromPresence(presence);

    topLabel.setIcon(presenceIcon);
    topLabel.setHorizontalTextPosition(JLabel.RIGHT);
    topLabel.setFont(new Font("Dialog", Font.BOLD, 15));
    topLabel.setForeground(Color.DARK_GRAY);

    // Add Calller Block
    buildInnerBlock();
}
 
Example #6
Source File: VCardManager.java    From Spark with Apache License 2.0 6 votes vote down vote up
public URL getAvatarURL(BareJid jid) {
    VCard vcard = getVCard(jid);
    if (vcard != null) {
        String hash = vcard.getAvatarHash();
        if (!ModelUtil.hasLength(hash)) {
            return null;
        }

        final File avatarFile = new File(contactsDir, hash);
        try {
            return avatarFile.toURI().toURL();
        }
        catch (MalformedURLException e) {
            Log.error(e);
        }
    }
    return null;
}
 
Example #7
Source File: OmemoDeviceTest.java    From Smack with Apache License 2.0 6 votes vote down vote up
/**
 * Test, if the equals() method works as intended.
 */
@Test
public void testEquals() {
    BareJid romeo, juliet, guyUnderTheBalcony;
    try {
        romeo = JidCreate.bareFrom("[email protected]");
        guyUnderTheBalcony = JidCreate.bareFrom("[email protected]/underTheBalcony");
        juliet = JidCreate.bareFrom("[email protected]");
    } catch (XmppStringprepException e) {
        Assert.fail(e.getMessage());
        return;
    }

    OmemoDevice r = new OmemoDevice(romeo, 1);
    OmemoDevice g = new OmemoDevice(guyUnderTheBalcony, 1);
    OmemoDevice r2 = new OmemoDevice(romeo, 2);
    OmemoDevice j = new OmemoDevice(juliet, 3);
    OmemoDevice j2 = new OmemoDevice(juliet, 1);

    assertTrue(r.equals(g));
    assertFalse(r.equals(r2));
    assertFalse(j.equals(j2));
    assertFalse(j2.equals(r2));
}
 
Example #8
Source File: AbstractOpenPgpTrustStore.java    From Smack with Apache License 2.0 6 votes vote down vote up
@Override
public Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException {
    Trust trust;
    Map<OpenPgpV4Fingerprint, Trust> trustMap = trustCache.get(owner);

    if (trustMap != null) {
        trust = trustMap.get(fingerprint);
        if (trust != null) {
            return trust;
        }
    } else {
        trustMap = new HashMap<>();
        trustCache.put(owner, trustMap);
    }

    trust = readTrust(owner, fingerprint);
    trustMap.put(fingerprint, trust);

    return trust;
}
 
Example #9
Source File: OmemoManager.java    From Smack with Apache License 2.0 6 votes vote down vote up
/**
 * Return all OmemoFingerprints of active devices of a contact.
 * TODO: Make more fail-safe
 *
 * @param contact contact
 * @return Map of all active devices of the contact and their fingerprints.
 *
 * @throws SmackException.NotLoggedInException if the XMPP connection is not authenticated.
 * @throws CorruptedOmemoKeyException if the OMEMO key is corrupted.
 * @throws CannotEstablishOmemoSessionException if no OMEMO session could be established.
 * @throws SmackException.NotConnectedException if the XMPP connection is not connected.
 * @throws InterruptedException if the calling thread was interrupted.
 * @throws SmackException.NoResponseException if there was no response from the remote entity.
 * @throws IOException if an I/O error occurred.
 */
public synchronized HashMap<OmemoDevice, OmemoFingerprint> getActiveFingerprints(BareJid contact)
        throws SmackException.NotLoggedInException, CorruptedOmemoKeyException,
        CannotEstablishOmemoSessionException, SmackException.NotConnectedException, InterruptedException,
        SmackException.NoResponseException, IOException {
    if (getOwnJid() == null) {
        throw new SmackException.NotLoggedInException();
    }

    HashMap<OmemoDevice, OmemoFingerprint> fingerprints = new HashMap<>();
    OmemoCachedDeviceList deviceList = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(),
            contact);

    for (int id : deviceList.getActiveDevices()) {
        OmemoDevice device = new OmemoDevice(contact, id);
        OmemoFingerprint fingerprint = getFingerprint(device);

        if (fingerprint != null) {
            fingerprints.put(device, fingerprint);
        }
    }

    return fingerprints;
}
 
Example #10
Source File: WorkgroupRosterTree.java    From Spark with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a new Roster Tree.
 *
 * @param exclusionJIDs the collection of jids to be excluded from the roster.
 * @param showAgents    true if agents should be visible.
 * @param workgroupList the list of workgroups.
 */
public WorkgroupRosterTree(Collection<? extends BareJid> exclusionJIDs, boolean showAgents, List workgroupList) {
    this.workgroupList = workgroupList;
    showUnavailableAgents = showAgents;
    exclusionList = exclusionJIDs;

    rootNode.setAllowsChildren(true);
    rosterTree = new Tree(rootNode);
    rosterTree.setCellRenderer(new JiveTreeCellRenderer());
    buildFromRoster();
    setLayout(new BorderLayout());

    final JPanel panel = new JPanel();
    panel.setLayout(new GridBagLayout());
    panel.setBackground(Color.white);

    final JScrollPane treeScroller = new JScrollPane(rosterTree);
    treeScroller.setBorder(BorderFactory.createEmptyBorder());
    panel.add(treeScroller, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));

    add(panel, BorderLayout.CENTER);
    for (int i = 0; i < rosterTree.getRowCount(); i++) {
        rosterTree.expandRow(i);
    }
}
 
Example #11
Source File: Omemo.java    From Zom-Android-XMPP with GNU General Public License v3.0 6 votes vote down vote up
private OmemoManager initOMemoManager(XMPPTCPConnection conn, BareJid altUser) {
    BareJid user;

    if (conn.getUser() != null) {
        user = conn.getUser().asBareJid();
    } else {
        user = altUser;
    }

    mOmemoStore = OmemoService.getInstance().getOmemoStoreBackend();
    int defaultDeviceId = mOmemoStore.getDefaultDeviceId(user);

    if (defaultDeviceId < 1) {
        defaultDeviceId = OmemoManager.randomDeviceId();
        mOmemoStore.setDefaultDeviceId(user, defaultDeviceId);
    }

    return OmemoManager.getInstanceFor(conn, defaultDeviceId);
}
 
Example #12
Source File: AbstractOpenPgpKeyStore.java    From Smack with Apache License 2.0 6 votes vote down vote up
@Override
public void importPublicKey(BareJid owner, PGPPublicKeyRing publicKeys) throws IOException, PGPException, MissingUserIdOnKeyException {

    if (!new BareJidUserId.PubRingSelectionStrategy().accept(owner, publicKeys)) {
        throw new MissingUserIdOnKeyException(owner, new OpenPgpV4Fingerprint(publicKeys));
    }

    PGPPublicKeyRing importKeys = BCUtil.removeUnassociatedKeysFromKeyRing(publicKeys, publicKeys.getPublicKey());

    PGPPublicKeyRingCollection publicKeyRings = getPublicKeysOf(owner);
    try {
        if (publicKeyRings != null) {
            publicKeyRings = PGPPublicKeyRingCollection.addPublicKeyRing(publicKeyRings, importKeys);
        } else {
            publicKeyRings = BCUtil.keyRingsToKeyRingCollection(importKeys);
        }
    } catch (IllegalArgumentException e) {
        LOGGER.log(Level.INFO, "Skipping public key ring " + Long.toHexString(importKeys.getPublicKey().getKeyID()) +
                " as it is already in the key ring of " + owner.toString());
    }
    this.publicKeyRingCollections.put(owner, publicKeyRings);
    writePublicKeysOf(owner, publicKeyRings);
}
 
Example #13
Source File: GatewayPlugin.java    From Spark with Apache License 2.0 5 votes vote down vote up
@Override
public Icon getIcon(BareJid jid) {
       DomainBareJid domain = jid.asDomainBareJid();
       Transport transport = TransportUtils.getTransport(domain);
       if (transport != null) {
           if (PresenceManager.isOnline(jid)) {
               return transport.getIcon();
           }
           else {
               return transport.getInactiveIcon();
           }
       }
       return null;
   }
 
Example #14
Source File: RosterManager.java    From mangosta-android with Apache License 2.0 5 votes vote down vote up
public HashMap<Jid, Presence.Type> getContacts()
        throws SmackException.NotLoggedInException, InterruptedException,
        SmackException.NotConnectedException {
    Roster roster = Roster.getInstanceFor(XMPPSession.getInstance().getXMPPConnection());
    if (!roster.isLoaded()) {
        roster.reloadAndWait();
    }

    String groupName = "Buddies";

    RosterGroup group = roster.getGroup(groupName);

    if (group == null) {
        roster.createGroup(groupName);
        group = roster.getGroup(groupName);
    }

    HashMap<Jid, Presence.Type> buddies = new HashMap<>();

    List<RosterEntry> entries = group.getEntries();
    for (RosterEntry entry : entries) {
        BareJid jid = entry.getJid();
        Presence.Type status = roster.getPresence(jid).getType();
        buddies.put(jid, status);
    }

    return buddies;
}
 
Example #15
Source File: Roster.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Check if the given JID is subscribed to the user's presence.
 * <p>
 * If the JID is subscribed to the user's presence then it is allowed to see the presence and
 * will get notified about presence changes. Also returns true, if the JID is the service
 * name of the XMPP connection (the "XMPP domain"), i.e. the XMPP service is treated like
 * having an implicit subscription to the users presence.
 * </p>
 * Note that if the roster is not loaded, then this method will always return false.
 *
 * @param jid TODO javadoc me please
 * @return true if the given JID is allowed to see the users presence.
 * @since 4.1
 */
public boolean isSubscribedToMyPresence(Jid jid) {
    if (jid == null) {
        return false;
    }
    BareJid bareJid = jid.asBareJid();
    if (connection().getXMPPServiceDomain().equals(bareJid)) {
        return true;
    }
    RosterEntry entry = getEntry(bareJid);
    if (entry == null) {
        return false;
    }
    return entry.canSeeMyPresence();
}
 
Example #16
Source File: IoTDiscoveryManager.java    From Smack with Apache License 2.0 5 votes vote down vote up
public void removeThing(Jid registry, BareJid thing, NodeInfo nodeInfo)
                throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
    interactWithRegistry(registry);

    IoTRemove iotRemove = new IoTRemove(thing, nodeInfo);
    iotRemove.setTo(registry);
    connection().createStanzaCollectorAndSend(iotRemove).nextResultOrThrow();

    // We no not update the ThingState here, as this is done in the <removed/> IQ handler above.;
}
 
Example #17
Source File: PubSubManager.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Get the PubSub manager for the given connection and PubSub service. Use <code>null</code> as argument for
 * pubSubService to retrieve a PubSubManager for the users PEP service.
 *
 * @param connection the XMPP connection.
 * @param pubSubService the PubSub service, may be <code>null</code>.
 * @return a PubSub manager for the connection and service.
 */
// CHECKSTYLE:OFF:RegexpSingleline
public static PubSubManager getInstanceFor(XMPPConnection connection, BareJid pubSubService) {
// CHECKSTYLE:ON:RegexpSingleline
    if (pubSubService != null && connection.isAuthenticated() && connection.getUser().asBareJid().equals(pubSubService)) {
        // PEP service.
        pubSubService = null;
    }

    PubSubManager pubSubManager;
    Map<BareJid, PubSubManager> managers;
    synchronized (INSTANCES) {
        managers = INSTANCES.get(connection);
        if (managers == null) {
            managers = new HashMap<>();
            INSTANCES.put(connection, managers);
        }
    }
    synchronized (managers) {
        pubSubManager = managers.get(pubSubService);
        if (pubSubManager == null) {
            pubSubManager = new PubSubManager(connection, pubSubService);
            managers.put(pubSubService, pubSubManager);
        }
    }

    return pubSubManager;
}
 
Example #18
Source File: AbstractOpenPgpStore.java    From Smack with Apache License 2.0 5 votes vote down vote up
@Override
public OpenPgpContact getOpenPgpContact(BareJid jid) {
    OpenPgpContact contact = contacts.get(jid);
    if (contact == null) {
        contact = new OpenPgpContact(jid, this);
        contacts.put(jid, contact);
    }
    return contact;
}
 
Example #19
Source File: FileBasedOpenPgpKeyStore.java    From Smack with Apache License 2.0 5 votes vote down vote up
@Override
public PGPSecretKeyRingCollection readSecretKeysOf(BareJid owner) throws IOException, PGPException {
    File file = getSecretKeyRingPath(owner);
    if (!file.exists()) {
        return null;
    }
    FileInputStream inputStream = FileUtils.prepareFileInputStream(file);

    PGPSecretKeyRingCollection collection = PGPainless.readKeyRing().secretKeyRingCollection(inputStream);
    inputStream.close();
    return collection;
}
 
Example #20
Source File: NotificationPlugin.java    From Spark with Apache License 2.0 5 votes vote down vote up
/**
 * Notify client that a user has come online.
 *
 * @param jid the jid of the user that has come online.
 * @param presence Presence of the online user.
 */
private void notifyUserOnline(final BareJid jid, final Presence presence) {
 try {
	 EventQueue.invokeAndWait( () -> {
            SparkToaster toaster = new SparkToaster();
            toaster.setDisplayTime(preferences.getNotificationsDisplayTime());
            toaster.setBorder(BorderFactory.createBevelBorder(0));
            toaster.setCustomAction(new ChatAction(jid));
            NotificationAlertUI alertUI = new NotificationAlertUI(jid, true, presence);

            toaster.setToasterHeight((int)alertUI.getPreferredSize().getHeight() + 40);

            int width = (int)alertUI.getPreferredSize().getWidth() + 40;
            if (width < 300) {
                width = 300;
            }

            toaster.setToasterWidth(width);

           toaster.showToaster(alertUI.topLabel.getText(), alertUI);
           toaster.setTitleAlert(new Font("Dialog", Font.BOLD, 13), presence);
        } );
 }
 catch(Exception ex) {
	Log.error(ex); 
 }
}
 
Example #21
Source File: FileBasedOmemoStore.java    From Smack with Apache License 2.0 5 votes vote down vote up
@Override
public void storeCachedDeviceList(OmemoDevice userDevice,
                                  BareJid contact,
                                  OmemoCachedDeviceList contactsDeviceList) throws IOException {
    if (contact == null) {
        return;
    }

    File activeDevices = hierarchy.getContactsActiveDevicesPath(userDevice, contact);
    writeIntegers(activeDevices, contactsDeviceList.getActiveDevices());

    File inactiveDevices = hierarchy.getContactsInactiveDevicesPath(userDevice, contact);
    writeIntegers(inactiveDevices, contactsDeviceList.getInactiveDevices());
}
 
Example #22
Source File: PresenceManager.java    From Spark with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true if the user is online and their status is available or free to chat.
 *
 * @param jidString the jid of the user.
 * @return true if the user is online and available.
 * @deprecated use {@link #isAvailable(BareJid)} instead.
 */
@Deprecated
public static boolean isAvailable(String jidString) {
    BareJid jid;
    try {
        jid = JidCreate.bareFrom(jidString);
    } catch (XmppStringprepException e) {
        throw new IllegalStateException(e);
    }
    return isAvailable(jid);
}
 
Example #23
Source File: RosterUtil.java    From Smack with Apache License 2.0 5 votes vote down vote up
public static void ensureNotSubscribedToEachOther(XMPPConnection connectionOne, XMPPConnection connectionTwo)
        throws NotConnectedException, InterruptedException {
    final Roster rosterOne = Roster.getInstanceFor(connectionOne);
    final BareJid jidOne = connectionOne.getUser().asBareJid();
    final Roster rosterTwo = Roster.getInstanceFor(connectionTwo);
    final BareJid jidTwo = connectionTwo.getUser().asBareJid();

    ensureNotSubscribed(rosterOne, jidTwo);
    ensureNotSubscribed(rosterTwo, jidOne);
}
 
Example #24
Source File: CannotEstablishOmemoSessionException.java    From Smack with Apache License 2.0 5 votes vote down vote up
private HashMap<OmemoDevice, Throwable> getFailsOfContact(BareJid contact) {
    HashMap<OmemoDevice, Throwable> h = failures.get(contact);
    if (h == null) {
        h = new HashMap<>();
        failures.put(contact, h);
    }
    return h;
}
 
Example #25
Source File: Roster.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Check if the XMPP entity this roster belongs to is subscribed to the presence of the given JID.
 *
 * @param jid the jid to check.
 * @return <code>true</code> if we are subscribed to the presence of the given jid.
 * @since 4.2
 */
public boolean iAmSubscribedTo(Jid jid) {
    if (jid == null) {
        return false;
    }
    BareJid bareJid = jid.asBareJid();
    RosterEntry entry = getEntry(bareJid);
    if (entry == null) {
        return false;
    }
    return entry.canSeeHisPresence();
}
 
Example #26
Source File: CannotEstablishOmemoSessionException.java    From Smack with Apache License 2.0 5 votes vote down vote up
/**
 * Return true, if there is at least one recipient, which would not be able to decipher the message on any of
 * their devices.
 *
 * @return true if the exception requires to be thrown
 */
public boolean requiresThrowing() {
    for (Map.Entry<BareJid, HashMap<OmemoDevice, Throwable>> entry : failures.entrySet()) {
        ArrayList<OmemoDevice> suc = successes.get(entry.getKey());
        if (suc == null || suc.isEmpty()) {
            return true;
        }
    }
    return false;
}
 
Example #27
Source File: GroupChatParticipantList.java    From Spark with Apache License 2.0 5 votes vote down vote up
protected void revokeMember(Resourcepart nickname) {
try {
    Occupant o = userManager.getOccupant(groupChatRoom, nickname);
       BareJid bareJid = o.getJid().asBareJid();
    chat.revokeMembership(Collections.singleton(bareJid));
} catch (XMPPException | SmackException | InterruptedException e) {
    groupChatRoom.getTranscriptWindow().insertNotificationMessage(
	    "No can do " + e.getMessage(), ChatManager.ERROR_COLOR);
}
   }
 
Example #28
Source File: VCardManager.java    From Spark with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a new vCard to the cache.
 *
 * @param jid   the jid of the user.
 * @param vcard the users vcard to cache.
 */
public void addVCard(BareJid jid, VCard vcard) {
    if (vcard == null)
    	return; 
    vcard.setJabberId(jid.toString());
    if (vcards.containsKey(jid) && vcards.get(jid).getError() == null && vcard.getError()!= null)
    {
    	return;
    	
    }
    vcards.put(jid, vcard);
}
 
Example #29
Source File: ContactGroup.java    From Spark with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a <code>ContactItem</code> by the users bare bareJID.
 *
 * @param bareJID the bareJID of the user.
 * @param searchInOffline should we search <code>ContactItem</code> in offline contacts
 * @return the ContactItem.
 */
public ContactItem getContactItemByJID(BareJid bareJID, boolean searchInOffline) {
    if (searchInOffline) {
        ContactItem item = getContactItemByJID(bareJID);
        if (item == null) {
            item = getOfflineContactItemByJID(bareJID);
        }
        return item;
    }
    return getContactItemByJID(bareJID);
}
 
Example #30
Source File: CachingOmemoStore.java    From Smack with Apache License 2.0 5 votes vote down vote up
@Override
public OmemoCachedDeviceList loadCachedDeviceList(OmemoDevice userDevice, BareJid contact) throws IOException {
    OmemoCachedDeviceList list = getCache(userDevice).deviceLists.get(contact);

    if (list == null && persistent != null) {
        list = persistent.loadCachedDeviceList(userDevice, contact);
        if (list != null) {
            getCache(userDevice).deviceLists.put(contact, list);
        }
    }

    return list == null ? new OmemoCachedDeviceList() : new OmemoCachedDeviceList(list);
}