<commit_before>/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.sip.communicator.impl.gui.main.contactlist;

import java.util.*;
import java.util.regex.*;

import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.gui.event.*;

/**
 * The <tt>SearchFilter</tt> is a <tt>ContactListFilter</tt> that filters the
 * contact list content by a filter string.
 *
 * @author <NAME>
 */
public class SearchFilter
    implements ContactListSearchFilter
{
    /**
     * The string, which we're searching.
     */
    protected String filterString;

    /**
     * The pattern to filter.
     */
    protected Pattern filterPattern;

    /**
     * The <tt>MetaContactListSource</tt> to search in.
     */
    private final MetaContactListSource mclSource;

    /**
     * The source contact list.
     */
    protected ContactList sourceContactList;

    /**
     * Creates an instance of <tt>SearchFilter</tt>.
     */
    public SearchFilter(MetaContactListSource contactListSource)
    {
        this.mclSource = contactListSource;
    }

    /**
     * Creates an instance of <tt>SearchFilter</tt>.
     */
    public SearchFilter(ContactList sourceContactList)
    {
        this.mclSource = null;
        this.sourceContactList = sourceContactList;
    }

    /**
     * Applies this filter to the default contact source.
     * @param filterQuery the query that tracks this filter.
     */
    public void applyFilter(FilterQuery filterQuery)
    {
        if (sourceContactList == null)
            sourceContactList = GuiActivator.getContactList();

        Iterator<UIContactSource> filterSources
            = sourceContactList.getContactSources().iterator();

        if (sourceContactList.getDefaultFilter()
                .equals(TreeContactList.presenceFilter))
        {
            MetaContactQuery defaultQuery
                = mclSource.queryMetaContactSource(filterPattern);

            defaultQuery.addContactQueryListener(sourceContactList);

            // First add the MetaContactListSource
            filterQuery.addContactQuery(defaultQuery);
        }
        else if (sourceContactList.getDefaultFilter()
                    .equals(TreeContactList.historyFilter))
        {
            filterSources = sourceContactList.getContactSources(
                ContactSourceService.HISTORY_TYPE).iterator();
        }

        // If we have stopped filtering in the mean time we return here.
        if (filterQuery.isCanceled())
            return;

        // Then we apply the filter on all its contact sources.
        while (filterSources.hasNext())
        {
            final UIContactSource filterSource
                = filterSources.next();

            // Don't search in history sources if this is disabled from the
            // corresponding configuration property.
            if (GuiActivator.getConfigurationService().getBoolean(
                    "net.java.sip.communicator.impl.gui"
                    + ".DISABLE_CALL_HISTORY_SEARCH_IN_CONTACT_LIST", false)
                && filterSource.getContactSourceService().getType()
                    == ContactSourceService.HISTORY_TYPE)
                continue;

            // If we have stopped filtering in the mean time we return here.
            if (filterQuery.isCanceled())
                return;

            ContactQuery query = applyFilter(filterSource);

            if (query.getStatus() == ContactQuery.QUERY_IN_PROGRESS)
                filterQuery.addContactQuery(query);
        }

        // Closes this filter to indicate that we finished adding queries to it.
        if (filterQuery.isRunning())
            filterQuery.close();
        else if (!sourceContactList.isEmpty())
            sourceContactList.selectFirstContact();
    }

    /**
     * Applies this filter to the given <tt>contactSource</tt>.
     *
     * @param contactSource the <tt>ExternalContactSource</tt> to apply the
     * filter to
     * @return the <tt>ContactQuery</tt> that tracks this filter
     */
    protected ContactQuery applyFilter(UIContactSource contactSource)
    {
        ContactSourceService sourceService
            = contactSource.getContactSourceService();

        ContactQuery contactQuery;
        if (sourceService instanceof ExtendedContactSourceService)
            contactQuery
                = ((ExtendedContactSourceService) sourceService)
                    .queryContactSource(filterPattern);
        else
            contactQuery = sourceService.queryContactSource(filterString);

        // Add first available results.
        this.addMatching(contactQuery.getQueryResults());

        contactQuery.addContactQueryListener(sourceContactList);

        return contactQuery;
    }

    /**
     * Indicates if the given <tt>uiGroup</tt> matches this filter.
     * @param uiContact the <tt>UIGroup</tt> to check
     * @return <tt>true</tt> if the given <tt>uiGroup</tt> matches the current
     * filter, <tt>false</tt> - otherwise
     */
    public boolean isMatching(UIContact uiContact)
    {
        Iterator<String> searchStrings = uiContact.getSearchStrings();

        if (searchStrings != null)
        {
            while (searchStrings.hasNext())
            {
                if (isMatching(searchStrings.next()))
                    return true;
            }
        }
        return false;
    }

    /**
     * For all groups we return false. If some of the child contacts of this
     * group matches this filter the group would be automatically added when
     * the contact is added in the list.
     * @param uiGroup the <tt>UIGroup</tt> to check
     * @return false
     */
    public boolean isMatching(UIGroup uiGroup)
    {
        return false;
    }

    /**
     * Creates the <tt>SearchFilter</tt> by specifying the string used for
     * filtering.
     * @param filter the String used for filtering
     */
    public void setFilterString(String filter)
    {
        // First escape all special characters from the given filter string.
        this.filterString = filter;

        // Then create the pattern.
        // By default, case-insensitive matching assumes that only characters
        // in the US-ASCII charset are being matched, that's why we use
        // the UNICODE_CASE flag to enable unicode case-insensitive matching.
        // Sun Bug ID: 6486934 "RegEx case_insensitive match is broken"
        this.filterPattern
                = Pattern.compile(
                        Pattern.quote(filterString),
                        Pattern.MULTILINE
                            | Pattern.CASE_INSENSITIVE
                            | Pattern.UNICODE_CASE);
    }

    /**
     * Checks if the given <tt>contact</tt> is matching the current filter.
     * A <tt>SourceContact</tt> would be matching the filter if its display
     * name is matching the search string.
     * @param contact the <tt>ContactListContactDescriptor</tt> to check
     * @return <tt>true</tt> to indicate that the given <tt>contact</tt> is
     * matching the current filter, otherwise returns <tt>false</tt>
     */
    private boolean isMatching(SourceContact contact)
    {
        return isMatching(contact.getDisplayName());
    }

    /**
     * Indicates if the given string matches this filter.
     * @param text the text to check
     * @return <tt>true</tt> to indicate that the given <tt>text</tt> matches
     * this filter, <tt>false</tt> - otherwise
     */
    private boolean isMatching(String text)
    {
        if (filterPattern != null)
            return filterPattern.matcher(text).find();

        return true;
    }

    /**
     * Adds the list of <tt>sourceContacts</tt> to the contact list.
     * @param sourceContacts the list of <tt>SourceContact</tt>s to add
     */
    protected void addMatching(List<SourceContact> sourceContacts)
    {
        Iterator<SourceContact> contactsIter = sourceContacts.iterator();

        while (contactsIter.hasNext())
            addSourceContact(contactsIter.next());
    }

    /**
     * Adds the given <tt>sourceContact</tt> to the contact list.
     * @param sourceContact the <tt>SourceContact</tt> to add
     */
    private void addSourceContact(SourceContact sourceContact)
    {
        ContactSourceService contactSource
            = sourceContact.getContactSource();

        UIContactSource sourceUI
            = sourceContactList.getContactSource(contactSource);

        if (sourceUI != null
            // ExtendedContactSourceService has already matched the
            // SourceContact over the pattern
            && (contactSource instanceof ExtendedContactSourceService)
                || isMatching(sourceContact))
        {
            sourceContactList.addContact(
                sourceUI.createUIContact(sourceContact),
                sourceUI.getUIGroup(),
                false,
                true);
        }
        else
            sourceUI.removeUIContact(sourceContact);
    }
}
<commit_msg>Removes unused import and improves code on previous commit that adds configuration property allowing to disable searches in call history<commit_after>/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.sip.communicator.impl.gui.main.contactlist;

import java.util.*;
import java.util.regex.*;

import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.gui.event.*;

/**
 * The <tt>SearchFilter</tt> is a <tt>ContactListFilter</tt> that filters the
 * contact list content by a filter string.
 *
 * @author <NAME>
 */
public class SearchFilter
    implements ContactListSearchFilter
{
    /**
     * The string, which we're searching.
     */
    protected String filterString;

    /**
     * The pattern to filter.
     */
    protected Pattern filterPattern;

    /**
     * The <tt>MetaContactListSource</tt> to search in.
     */
    private final MetaContactListSource mclSource;

    /**
     * The source contact list.
     */
    protected ContactList sourceContactList;

    /**
     * The name of the property indicating if searches in call history are
     * enabled.
     */
    protected String DISABLE_CALL_HISTORY_SEARCH_PROP
        = "net.java.sip.communicator.impl.gui"
                + ".DISABLE_CALL_HISTORY_SEARCH_IN_CONTACT_LIST";

    /**
     * Creates an instance of <tt>SearchFilter</tt>.
     */
    public SearchFilter(MetaContactListSource contactListSource)
    {
        this.mclSource = contactListSource;
    }

    /**
     * Creates an instance of <tt>SearchFilter</tt>.
     */
    public SearchFilter(ContactList sourceContactList)
    {
        this.mclSource = null;
        this.sourceContactList = sourceContactList;
    }

    /**
     * Applies this filter to the default contact source.
     * @param filterQuery the query that tracks this filter.
     */
    public void applyFilter(FilterQuery filterQuery)
    {
        if (sourceContactList == null)
            sourceContactList = GuiActivator.getContactList();

        Iterator<UIContactSource> filterSources
            = sourceContactList.getContactSources().iterator();

        if (sourceContactList.getDefaultFilter()
                .equals(TreeContactList.presenceFilter))
        {
            MetaContactQuery defaultQuery
                = mclSource.queryMetaContactSource(filterPattern);

            defaultQuery.addContactQueryListener(sourceContactList);

            // First add the MetaContactListSource
            filterQuery.addContactQuery(defaultQuery);
        }
        else if (sourceContactList.getDefaultFilter()
                    .equals(TreeContactList.historyFilter))
        {
            filterSources = sourceContactList.getContactSources(
                ContactSourceService.HISTORY_TYPE).iterator();
        }

        // If we have stopped filtering in the mean time we return here.
        if (filterQuery.isCanceled())
            return;

        // Then we apply the filter on all its contact sources.
        while (filterSources.hasNext())
        {
            final UIContactSource filterSource
                = filterSources.next();

            // Don't search in history sources if this is disabled from the
            // corresponding configuration property.
            if (sourceContactList.getDefaultFilter()
                    .equals(TreeContactList.presenceFilter)
                && GuiActivator.getConfigurationService().getBoolean(
                    DISABLE_CALL_HISTORY_SEARCH_PROP, true)
                && filterSource.getContactSourceService().getType()
                    == ContactSourceService.HISTORY_TYPE)
                continue;

            // If we have stopped filtering in the mean time we return here.
            if (filterQuery.isCanceled())
                return;

            ContactQuery query = applyFilter(filterSource);

            if (query.getStatus() == ContactQuery.QUERY_IN_PROGRESS)
                filterQuery.addContactQuery(query);
        }

        // Closes this filter to indicate that we finished adding queries to it.
        if (filterQuery.isRunning())
            filterQuery.close();
        else if (!sourceContactList.isEmpty())
            sourceContactList.selectFirstContact();
    }

    /**
     * Applies this filter to the given <tt>contactSource</tt>.
     *
     * @param contactSource the <tt>ExternalContactSource</tt> to apply the
     * filter to
     * @return the <tt>ContactQuery</tt> that tracks this filter
     */
    protected ContactQuery applyFilter(UIContactSource contactSource)
    {
        ContactSourceService sourceService
            = contactSource.getContactSourceService();

        ContactQuery contactQuery;
        if (sourceService instanceof ExtendedContactSourceService)
            contactQuery
                = ((ExtendedContactSourceService) sourceService)
                    .queryContactSource(filterPattern);
        else
            contactQuery = sourceService.queryContactSource(filterString);

        // Add first available results.
        this.addMatching(contactQuery.getQueryResults());

        contactQuery.addContactQueryListener(sourceContactList);

        return contactQuery;
    }

    /**
     * Indicates if the given <tt>uiGroup</tt> matches this filter.
     * @param uiContact the <tt>UIGroup</tt> to check
     * @return <tt>true</tt> if the given <tt>uiGroup</tt> matches the current
     * filter, <tt>false</tt> - otherwise
     */
    public boolean isMatching(UIContact uiContact)
    {
        Iterator<String> searchStrings = uiContact.getSearchStrings();

        if (searchStrings != null)
        {
            while (searchStrings.hasNext())
            {
                if (isMatching(searchStrings.next()))
                    return true;
            }
        }
        return false;
    }

    /**
     * For all groups we return false. If some of the child contacts of this
     * group matches this filter the group would be automatically added when
     * the contact is added in the list.
     * @param uiGroup the <tt>UIGroup</tt> to check
     * @return false
     */
    public boolean isMatching(UIGroup uiGroup)
    {
        return false;
    }

    /**
     * Creates the <tt>SearchFilter</tt> by specifying the string used for
     * filtering.
     * @param filter the String used for filtering
     */
    public void setFilterString(String filter)
    {
        // First escape all special characters from the given filter string.
        this.filterString = filter;

        // Then create the pattern.
        // By default, case-insensitive matching assumes that only characters
        // in the US-ASCII charset are being matched, that's why we use
        // the UNICODE_CASE flag to enable unicode case-insensitive matching.
        // Sun Bug ID: 6486934 "RegEx case_insensitive match is broken"
        this.filterPattern
                = Pattern.compile(
                        Pattern.quote(filterString),
                        Pattern.MULTILINE
                            | Pattern.CASE_INSENSITIVE
                            | Pattern.UNICODE_CASE);
    }

    /**
     * Checks if the given <tt>contact</tt> is matching the current filter.
     * A <tt>SourceContact</tt> would be matching the filter if its display
     * name is matching the search string.
     * @param contact the <tt>ContactListContactDescriptor</tt> to check
     * @return <tt>true</tt> to indicate that the given <tt>contact</tt> is
     * matching the current filter, otherwise returns <tt>false</tt>
     */
    private boolean isMatching(SourceContact contact)
    {
        return isMatching(contact.getDisplayName());
    }

    /**
     * Indicates if the given string matches this filter.
     * @param text the text to check
     * @return <tt>true</tt> to indicate that the given <tt>text</tt> matches
     * this filter, <tt>false</tt> - otherwise
     */
    private boolean isMatching(String text)
    {
        if (filterPattern != null)
            return filterPattern.matcher(text).find();

        return true;
    }

    /**
     * Adds the list of <tt>sourceContacts</tt> to the contact list.
     * @param sourceContacts the list of <tt>SourceContact</tt>s to add
     */
    protected void addMatching(List<SourceContact> sourceContacts)
    {
        Iterator<SourceContact> contactsIter = sourceContacts.iterator();

        while (contactsIter.hasNext())
            addSourceContact(contactsIter.next());
    }

    /**
     * Adds the given <tt>sourceContact</tt> to the contact list.
     * @param sourceContact the <tt>SourceContact</tt> to add
     */
    private void addSourceContact(SourceContact sourceContact)
    {
        ContactSourceService contactSource
            = sourceContact.getContactSource();

        UIContactSource sourceUI
            = sourceContactList.getContactSource(contactSource);

        if (sourceUI != null
            // ExtendedContactSourceService has already matched the
            // SourceContact over the pattern
            && (contactSource instanceof ExtendedContactSourceService)
                || isMatching(sourceContact))
        {
            sourceContactList.addContact(
                sourceUI.createUIContact(sourceContact),
                sourceUI.getUIGroup(),
                false,
                true);
        }
        else
            sourceUI.removeUIContact(sourceContact);
    }
}

{'fraction_non_alphanumeric': 0.08634000315109501, 'fraction_numerical': 0.0007352555012866971, 'mean_word_length': 2.239537257570602, 'pattern_counts': {'":': 0, '<': 125, '<?xml version=': 0, '>': 125, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2145657', 'n_tokens_mistral': 4940, 'n_tokens_neox': 4781, 'n_words': 1316}