/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* 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 net.java.sip.communicator.impl.protocol.jabber;
import java.util.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.ReportedData.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
/**
* This operation set provides utility methods for user search implementation.
*
* @author Hristo Terezov
*/
public class OperationSetUserSearchJabberImpl
implements OperationSetUserSearch, RegistrationStateChangeListener
{
/**
* The logger.
*/
private static final Logger logger =
Logger.getLogger(OperationSetUserSearchJabberImpl.class);
/**
* The UserSearchManager instance which actually implements the
* user search.
*/
private UserSearchManager searchManager = null;
/**
* The ProtocolProviderService instance.
*/
private ProtocolProviderServiceJabberImpl provider;
/**
* The user search service name.
*/
private String serviceName = null;
/**
* Whether the user search service is enabled or not.
*/
private Boolean userSearchEnabled = false;
/**
* A list of UserSearchProviderListener listeners which will be
* notified when the provider user search feature is enabled or disabled.
*/
private List listeners
= new ArrayList();
/**
* The property name of the user search service name.
*/
private static final String USER_SEARCH_SERVICE_NAME
= "USER_SEARCH_SERVICE_NAME";
/**
* Constructs new OperationSetUserSearchJabberImpl instance.
* @param provider the provider associated with the operation set.
*/
protected OperationSetUserSearchJabberImpl(
ProtocolProviderServiceJabberImpl provider)
{
this.provider = provider;
serviceName = provider.getAccountID().getAccountPropertyString(
USER_SEARCH_SERVICE_NAME, "");
if(serviceName.equals(""))
{
provider.addRegistrationStateChangeListener(this);
}
else
{
setUserSearchEnabled(true);
}
}
/**
* Sets the userSearchEnabled property and fires
* UserSearchProviderEvent event.
*
* @param isEnabled the value to be set.
*/
private void setUserSearchEnabled(boolean isEnabled)
{
userSearchEnabled = isEnabled;
int type = (isEnabled? UserSearchProviderEvent.PROVIDER_ADDED
: UserSearchProviderEvent.PROVIDER_REMOVED);
fireUserSearchProviderEvent(new UserSearchProviderEvent(provider, type));
}
/**
* Fires UserSearchProviderEvent event.
* @param event the event to be fired.
*/
private void fireUserSearchProviderEvent(UserSearchProviderEvent event)
{
List tmpListeners;
synchronized (listeners)
{
tmpListeners = new ArrayList(listeners);
}
for(UserSearchProviderListener l : tmpListeners)
l.onUserSearchProviderEvent(event);
}
@Override
public void registrationStateChanged(RegistrationStateChangeEvent evt)
{
if(evt.getNewState().equals(RegistrationState.REGISTERED))
{
discoverSearchService();
}
else if(evt.getNewState() == RegistrationState.UNREGISTERED
|| evt.getNewState() == RegistrationState.AUTHENTICATION_FAILED
|| evt.getNewState() == RegistrationState.CONNECTION_FAILED)
{
synchronized (userSearchEnabled)
{
setUserSearchEnabled(false);
}
}
}
/**
* Tries to discover the user search service name.
*/
private void discoverSearchService()
{
new Thread()
{
public void run()
{
synchronized (userSearchEnabled)
{
List serviceNames
= UserSearchManager.getAvailableServiceNames(
provider);
if(!serviceNames.isEmpty())
{
serviceName = serviceNames.get(0);
setUserSearchEnabled(true);
}
else
{
setUserSearchEnabled(false);
}
}
};
}.start();
}
/**
* Creates the UserSearchManager instance.
*/
public void createSearchManager()
{
if(searchManager == null)
{
searchManager
= new UserSearchManager(provider.getConnection(), serviceName);
}
}
/**
* Releases the UserSearchManager instance.
*/
public void removeSearchManager()
{
searchManager = null;
}
/**
* Performs user search for the searched string and returns the JIDs of the
* found contacts.
*
* @param searchedString the text we want to query the server.
* @return the list of found JIDs
*/
public List search(String searchedString)
{
ReportedData data = null;
try
{
data = searchManager.searchForString(searchedString);
}
catch (XMPPException e)
{
logger.error(e);
return null;
}
if(data == null)
{
logger.error("No data have been received from server.");
return null;
}
Iterator columns = data.getColumns();
Iterator rows = data.getRows();
if(columns == null || rows == null)
{
logger.error("The received data is corrupted.");
return null;
}
Column jidColumn = null;
while(columns.hasNext())
{
Column tmpCollumn = columns.next();
if(tmpCollumn.getType().equals(FormField.TYPE_JID_SINGLE))
{
jidColumn = tmpCollumn;
break;
}
}
if(jidColumn == null)
{
logger.error("No jid collumn provided by the server.");
return null;
}
List result = new ArrayList();
while(rows.hasNext())
{
Row row = rows.next();
result.add((String)row.getValues(jidColumn.getVariable()).next());
}
return result;
}
/**
* Adds UserSearchProviderListener instance to the list of
* listeners.
*
* @param l the listener to be added
*/
public void addUserSearchProviderListener(UserSearchProviderListener l)
{
synchronized (listeners)
{
if(!listeners.contains(l))
listeners.add(l);
}
}
/**
* Removes UserSearchProviderListener instance from the list of
* listeners.
*
* @param l the listener to be removed
*/
public void removeUserSearchProviderListener(UserSearchProviderListener l)
{
synchronized (listeners)
{
listeners.remove(l);
}
}
/**
* Returns true if the user search service is enabled.
*
* @return true if the user search service is enabled.
*/
public boolean isEnabled()
{
return userSearchEnabled;
}
}