Search in sources :

Example 16 with Mention

use of org.thoughtcrime.securesms.database.model.Mention in project Signal-Android by signalapp.

the class MentionDatabase method readMentions.

@NonNull
private Map<Long, List<Mention>> readMentions(@Nullable Cursor cursor) {
    Map<Long, List<Mention>> mentions = new HashMap<>();
    while (cursor != null && cursor.moveToNext()) {
        long messageId = CursorUtil.requireLong(cursor, MESSAGE_ID);
        List<Mention> messageMentions = mentions.get(messageId);
        if (messageMentions == null) {
            messageMentions = new LinkedList<>();
            mentions.put(messageId, messageMentions);
        }
        messageMentions.add(new Mention(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)), CursorUtil.requireInt(cursor, RANGE_START), CursorUtil.requireInt(cursor, RANGE_LENGTH)));
    }
    return mentions;
}
Also used : HashMap(java.util.HashMap) Mention(org.thoughtcrime.securesms.database.model.Mention) List(java.util.List) LinkedList(java.util.LinkedList) NonNull(androidx.annotation.NonNull)

Example 17 with Mention

use of org.thoughtcrime.securesms.database.model.Mention in project Signal-Android by signalapp.

the class MentionDatabase method getMentionsForMessage.

@NonNull
public List<Mention> getMentionsForMessage(long messageId) {
    SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
    List<Mention> mentions = new LinkedList<>();
    try (Cursor cursor = db.query(TABLE_NAME, null, MESSAGE_ID + " = ?", SqlUtil.buildArgs(messageId), null, null, null)) {
        while (cursor != null && cursor.moveToNext()) {
            mentions.add(new Mention(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)), CursorUtil.requireInt(cursor, RANGE_START), CursorUtil.requireInt(cursor, RANGE_LENGTH)));
        }
    }
    return mentions;
}
Also used : Mention(org.thoughtcrime.securesms.database.model.Mention) Cursor(android.database.Cursor) LinkedList(java.util.LinkedList) NonNull(androidx.annotation.NonNull)

Example 18 with Mention

use of org.thoughtcrime.securesms.database.model.Mention in project Signal-Android by signalapp.

the class MessageContentProcessor method getValidatedQuote.

private Optional<QuoteModel> getValidatedQuote(Optional<SignalServiceDataMessage.Quote> quote) {
    if (!quote.isPresent())
        return Optional.absent();
    if (quote.get().getId() <= 0) {
        warn("Received quote without an ID! Ignoring...");
        return Optional.absent();
    }
    if (quote.get().getAuthor() == null) {
        warn("Received quote without an author! Ignoring...");
        return Optional.absent();
    }
    RecipientId author = Recipient.externalPush(quote.get().getAuthor()).getId();
    MessageRecord message = SignalDatabase.mmsSms().getMessageFor(quote.get().getId(), author);
    if (message != null && !message.isRemoteDelete()) {
        log("Found matching message record...");
        List<Attachment> attachments = new LinkedList<>();
        List<Mention> mentions = new LinkedList<>();
        if (message.isMms()) {
            MmsMessageRecord mmsMessage = (MmsMessageRecord) message;
            mentions.addAll(SignalDatabase.mentions().getMentionsForMessage(mmsMessage.getId()));
            if (mmsMessage.isViewOnce()) {
                attachments.add(new TombstoneAttachment(MediaUtil.VIEW_ONCE, true));
            } else {
                attachments = mmsMessage.getSlideDeck().asAttachments();
                if (attachments.isEmpty()) {
                    attachments.addAll(Stream.of(mmsMessage.getLinkPreviews()).filter(lp -> lp.getThumbnail().isPresent()).map(lp -> lp.getThumbnail().get()).toList());
                }
            }
        }
        return Optional.of(new QuoteModel(quote.get().getId(), author, message.getBody(), false, attachments, mentions));
    } else if (message != null) {
        warn("Found the target for the quote, but it's flagged as remotely deleted.");
    }
    warn("Didn't find matching message record...");
    return Optional.of(new QuoteModel(quote.get().getId(), author, quote.get().getText(), true, PointerAttachment.forPointers(quote.get().getAttachments()), getMentions(quote.get().getMentions())));
}
Also used : LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) StickerPackOperationMessage(org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage) NonNull(androidx.annotation.NonNull) RecipientUtil(org.thoughtcrime.securesms.recipients.RecipientUtil) PaymentTransactionCheckJob(org.thoughtcrime.securesms.jobs.PaymentTransactionCheckJob) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) LinkPreviewUtil(org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil) SecureRandom(java.security.SecureRandom) SignalServiceContent(org.whispersystems.signalservice.api.messages.SignalServiceContent) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) RequestGroupInfoJob(org.thoughtcrime.securesms.jobs.RequestGroupInfoJob) Map(java.util.Map) GroupChangeBusyException(org.thoughtcrime.securesms.groups.GroupChangeBusyException) ThreadRecord(org.thoughtcrime.securesms.database.model.ThreadRecord) OutgoingTextMessage(org.thoughtcrime.securesms.sms.OutgoingTextMessage) MultiDeviceGroupUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) ThreadDatabase(org.thoughtcrime.securesms.database.ThreadDatabase) Nullable(androidx.annotation.Nullable) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) StickerPackDownloadJob(org.thoughtcrime.securesms.jobs.StickerPackDownloadJob) SignalServiceGroupV2(org.whispersystems.signalservice.api.messages.SignalServiceGroupV2) MessageLogEntry(org.thoughtcrime.securesms.database.model.MessageLogEntry) CallId(org.signal.ringrtc.CallId) GroupUtil(org.thoughtcrime.securesms.util.GroupUtil) PendingRetryReceiptModel(org.thoughtcrime.securesms.database.model.PendingRetryReceiptModel) RefreshOwnProfileJob(org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob) Attachment(org.thoughtcrime.securesms.attachments.Attachment) MultiDeviceBlockedUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) MediaUtil(org.thoughtcrime.securesms.util.MediaUtil) MmsSmsDatabase(org.thoughtcrime.securesms.database.MmsSmsDatabase) StickerDatabase(org.thoughtcrime.securesms.database.StickerDatabase) GroupsV1MigrationUtil(org.thoughtcrime.securesms.groups.GroupsV1MigrationUtil) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) SignalServiceTypingMessage(org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage) ProfileKeySendJob(org.thoughtcrime.securesms.jobs.ProfileKeySendJob) Stream(com.annimon.stream.Stream) PaymentMetaDataUtil(org.thoughtcrime.securesms.database.PaymentMetaDataUtil) Util(org.thoughtcrime.securesms.util.Util) RefreshAttributesJob(org.thoughtcrime.securesms.jobs.RefreshAttributesJob) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) RetrieveProfileJob(org.thoughtcrime.securesms.jobs.RetrieveProfileJob) ArrayList(java.util.ArrayList) PaymentDatabase(org.thoughtcrime.securesms.database.PaymentDatabase) BlockedListMessage(org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage) ContactModelMapper(org.thoughtcrime.securesms.contactshare.ContactModelMapper) MultiDeviceConfigurationUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob) NullMessageSendJob(org.thoughtcrime.securesms.jobs.NullMessageSendJob) IncomingEncryptedMessage(org.thoughtcrime.securesms.sms.IncomingEncryptedMessage) OutgoingEndSessionMessage(org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage) HangupMessage(org.whispersystems.signalservice.api.messages.calls.HangupMessage) EmojiUtil(org.thoughtcrime.securesms.components.emoji.EmojiUtil) ECPublicKey(org.whispersystems.libsignal.ecc.ECPublicKey) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup) SignalServiceCallMessage(org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage) ReadMessage(org.whispersystems.signalservice.api.messages.multidevice.ReadMessage) IncomingEndSessionMessage(org.thoughtcrime.securesms.sms.IncomingEndSessionMessage) ViewOnceOpenMessage(org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage) MessageRequestResponseMessage(org.whispersystems.signalservice.api.messages.multidevice.MessageRequestResponseMessage) OutgoingEncryptedMessage(org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage) KeysMessage(org.whispersystems.signalservice.api.messages.multidevice.KeysMessage) DistributionId(org.whispersystems.signalservice.api.push.DistributionId) GroupReceiptInfo(org.thoughtcrime.securesms.database.GroupReceiptDatabase.GroupReceiptInfo) RequestMessage(org.whispersystems.signalservice.api.messages.multidevice.RequestMessage) IdentityUtil(org.thoughtcrime.securesms.util.IdentityUtil) MessageId(org.thoughtcrime.securesms.database.model.MessageId) Collectors(com.annimon.stream.Collectors) GroupReceiptDatabase(org.thoughtcrime.securesms.database.GroupReceiptDatabase) Contact(org.thoughtcrime.securesms.contactshare.Contact) TextUtils(android.text.TextUtils) Hex(org.thoughtcrime.securesms.util.Hex) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) StickerLocator(org.thoughtcrime.securesms.stickers.StickerLocator) GroupV1MessageProcessor(org.thoughtcrime.securesms.groups.GroupV1MessageProcessor) TrimThreadJob(org.thoughtcrime.securesms.jobs.TrimThreadJob) IncomingMediaMessage(org.thoughtcrime.securesms.mms.IncomingMediaMessage) Money(org.whispersystems.signalservice.api.payments.Money) SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) VerifiedMessage(org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage) MessageNotifier(org.thoughtcrime.securesms.notifications.MessageNotifier) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SlideDeck(org.thoughtcrime.securesms.mms.SlideDeck) AttachmentDownloadJob(org.thoughtcrime.securesms.jobs.AttachmentDownloadJob) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) JobManager(org.thoughtcrime.securesms.jobmanager.JobManager) MultiDeviceStickerPackSyncJob(org.thoughtcrime.securesms.jobs.MultiDeviceStickerPackSyncJob) WebRtcData(org.thoughtcrime.securesms.service.webrtc.WebRtcData) SentTranscriptMessage(org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage) Mention(org.thoughtcrime.securesms.database.model.Mention) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) AutomaticSessionResetJob(org.thoughtcrime.securesms.jobs.AutomaticSessionResetJob) SecurityEvent(org.thoughtcrime.securesms.crypto.SecurityEvent) StorageSyncHelper(org.thoughtcrime.securesms.storage.StorageSyncHelper) Locale(java.util.Locale) ResendMessageJob(org.thoughtcrime.securesms.jobs.ResendMessageJob) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) Recipient(org.thoughtcrime.securesms.recipients.Recipient) BusyMessage(org.whispersystems.signalservice.api.messages.calls.BusyMessage) StickerSlide(org.thoughtcrime.securesms.mms.StickerSlide) MultiDeviceContactSyncJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactSyncJob) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) PaymentLedgerUpdateJob(org.thoughtcrime.securesms.jobs.PaymentLedgerUpdateJob) Collection(java.util.Collection) ProfileKeyUtil(org.thoughtcrime.securesms.crypto.ProfileKeyUtil) SendDeliveryReceiptJob(org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob) OutgoingSecureMediaMessage(org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage) UUID(java.util.UUID) SenderKeyDistributionSendJob(org.thoughtcrime.securesms.jobs.SenderKeyDistributionSendJob) OutgoingExpirationUpdateMessage(org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) FeatureFlags(org.thoughtcrime.securesms.util.FeatureFlags) List(java.util.List) MarkReadReceiver(org.thoughtcrime.securesms.notifications.MarkReadReceiver) ViewedMessage(org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage) GroupNotAMemberException(org.thoughtcrime.securesms.groups.GroupNotAMemberException) GroupId(org.thoughtcrime.securesms.groups.GroupId) SharedContact(org.whispersystems.signalservice.api.messages.shared.SharedContact) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) ContactsMessage(org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage) GroupV2UpdateSelfProfileKeyJob(org.thoughtcrime.securesms.jobs.GroupV2UpdateSelfProfileKeyJob) IncomingTextMessage(org.thoughtcrime.securesms.sms.IncomingTextMessage) SignalServiceReceiptMessage(org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage) InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) PushProcessMessageJob(org.thoughtcrime.securesms.jobs.PushProcessMessageJob) AnswerMessage(org.whispersystems.signalservice.api.messages.calls.AnswerMessage) MultiDevicePniIdentityUpdateJob(org.thoughtcrime.securesms.jobs.MultiDevicePniIdentityUpdateJob) Context(android.content.Context) ConfigurationMessage(org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage) RemotePeer(org.thoughtcrime.securesms.ringrtc.RemotePeer) BadGroupIdException(org.thoughtcrime.securesms.groups.BadGroupIdException) HashMap(java.util.HashMap) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) OfferMessage(org.whispersystems.signalservice.api.messages.calls.OfferMessage) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) OpaqueMessage(org.whispersystems.signalservice.api.messages.calls.OpaqueMessage) GroupManager(org.thoughtcrime.securesms.groups.GroupManager) SuppressLint(android.annotation.SuppressLint) GroupCallPeekJob(org.thoughtcrime.securesms.jobs.GroupCallPeekJob) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel) Build(android.os.Build) LinkedList(java.util.LinkedList) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) MultiDeviceKeysUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceKeysUpdateJob) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) DecryptionErrorMessage(org.whispersystems.libsignal.protocol.DecryptionErrorMessage) StickerRecord(org.thoughtcrime.securesms.database.model.StickerRecord) MmsException(org.thoughtcrime.securesms.mms.MmsException) RemoteDeleteUtil(org.thoughtcrime.securesms.util.RemoteDeleteUtil) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) OutgoingPaymentMessage(org.whispersystems.signalservice.api.messages.multidevice.OutgoingPaymentMessage) TimeUnit(java.util.concurrent.TimeUnit) IceUpdateMessage(org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage) RateLimitUtil(org.thoughtcrime.securesms.ratelimit.RateLimitUtil) SignalServiceSyncMessage(org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage) SessionRecord(org.whispersystems.libsignal.state.SessionRecord) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) Mention(org.thoughtcrime.securesms.database.model.Mention) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) PointerAttachment(org.thoughtcrime.securesms.attachments.PointerAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) UriAttachment(org.thoughtcrime.securesms.attachments.UriAttachment) TombstoneAttachment(org.thoughtcrime.securesms.attachments.TombstoneAttachment) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) LinkedList(java.util.LinkedList) QuoteModel(org.thoughtcrime.securesms.mms.QuoteModel)

Example 19 with Mention

use of org.thoughtcrime.securesms.database.model.Mention in project Signal-Android by signalapp.

the class SearchRepository method updateSnippetWithDisplayNames.

@NonNull
private String updateSnippetWithDisplayNames(@NonNull String body, @NonNull String bodySnippet, @NonNull List<Mention> mentions) {
    String cleanSnippet = bodySnippet;
    int startOffset = 0;
    if (cleanSnippet.startsWith(SNIPPET_WRAP)) {
        cleanSnippet = cleanSnippet.substring(SNIPPET_WRAP.length());
        startOffset = SNIPPET_WRAP.length();
    }
    if (cleanSnippet.endsWith(SNIPPET_WRAP)) {
        cleanSnippet = cleanSnippet.substring(0, cleanSnippet.length() - SNIPPET_WRAP.length());
    }
    int startIndex = body.indexOf(cleanSnippet);
    if (startIndex != -1) {
        List<Mention> adjustMentions = new ArrayList<>(mentions.size());
        for (Mention mention : mentions) {
            int adjustedStart = mention.getStart() - startIndex + startOffset;
            if (adjustedStart >= 0 && adjustedStart + mention.getLength() <= cleanSnippet.length()) {
                adjustMentions.add(new Mention(mention.getRecipientId(), adjustedStart, mention.getLength()));
            }
        }
        // noinspection ConstantConditions
        return MentionUtil.updateBodyAndMentionsWithDisplayNames(context, bodySnippet, adjustMentions).getBody().toString();
    }
    return bodySnippet;
}
Also used : Mention(org.thoughtcrime.securesms.database.model.Mention) ArrayList(java.util.ArrayList) NonNull(androidx.annotation.NonNull)

Example 20 with Mention

use of org.thoughtcrime.securesms.database.model.Mention in project Signal-Android by signalapp.

the class SearchRepository method queryMentions.

@NonNull
private List<MessageResult> queryMentions(@NonNull List<String> cleanQueries) {
    Set<RecipientId> recipientIds = new HashSet<>();
    for (String cleanQuery : cleanQueries) {
        for (Recipient recipient : recipientDatabase.queryRecipientsForMentions(cleanQuery)) {
            recipientIds.add(recipient.getId());
        }
    }
    Map<Long, List<Mention>> mentionQueryResults = mentionDatabase.getMentionsContainingRecipients(recipientIds, 500);
    if (mentionQueryResults.isEmpty()) {
        return Collections.emptyList();
    }
    List<MessageResult> results = new ArrayList<>();
    try (MessageDatabase.Reader reader = mmsDatabase.getMessages(mentionQueryResults.keySet())) {
        MessageRecord record;
        while ((record = reader.getNext()) != null) {
            List<Mention> mentions = mentionQueryResults.get(record.getId());
            if (Util.hasItems(mentions)) {
                MentionUtil.UpdatedBodyAndMentions updated = MentionUtil.updateBodyAndMentionsWithDisplayNames(context, record.getBody(), mentions);
                String updatedBody = updated.getBody() != null ? updated.getBody().toString() : record.getBody();
                String updatedSnippet = makeSnippet(cleanQueries, updatedBody);
                // noinspection ConstantConditions
                results.add(new MessageResult(threadDatabase.getRecipientForThreadId(record.getThreadId()), record.getRecipient(), updatedBody, updatedSnippet, record.getThreadId(), record.getId(), record.getDateReceived(), true));
            }
        }
    }
    return results;
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ArrayList(java.util.ArrayList) Recipient(org.thoughtcrime.securesms.recipients.Recipient) MentionUtil(org.thoughtcrime.securesms.database.MentionUtil) Mention(org.thoughtcrime.securesms.database.model.Mention) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) NonNull(androidx.annotation.NonNull)

Aggregations

Mention (org.thoughtcrime.securesms.database.model.Mention)32 NonNull (androidx.annotation.NonNull)20 ArrayList (java.util.ArrayList)20 LinkedList (java.util.LinkedList)14 List (java.util.List)14 Context (android.content.Context)12 Nullable (androidx.annotation.Nullable)12 MessageRecord (org.thoughtcrime.securesms.database.model.MessageRecord)12 QuoteModel (org.thoughtcrime.securesms.mms.QuoteModel)12 SlideDeck (org.thoughtcrime.securesms.mms.SlideDeck)12 Recipient (org.thoughtcrime.securesms.recipients.Recipient)12 OutgoingMediaMessage (org.thoughtcrime.securesms.mms.OutgoingMediaMessage)10 OutgoingSecureMediaMessage (org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage)10 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)10 Cursor (android.database.Cursor)8 Collectors (com.annimon.stream.Collectors)8 Stream (com.annimon.stream.Stream)8 IOException (java.io.IOException)8 SecureRandom (java.security.SecureRandom)8 Collections (java.util.Collections)8