Implements user search contact source.

ice4sip 5080
hristoterezov 12 years ago
parent e4627ba7d2
commit fa49941803

@ -1086,7 +1086,8 @@
bundle-globalshortcut,bundle-plugin-msofficecomm,bundle-libjitsi,
bundle-customcontactactions, bundle-phonenumbercontactsource,
bundle-demuxcontactsource, bundle-muc,
bundle-desktoputil,bundle-globaldisplaydetails,
bundle-desktoputil,bundle-globaldisplaydetails,
bundle-usersearch,
bundle-plugin-propertieseditor,bundle-plugin-accountinfo,
bundle-guava,bundle-hsql"/>
@ -2874,6 +2875,15 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
<!-- BUNDLE-PHONE-NUMBER-CONTACT-SOURCE -->
<target name="bundle-usersearch">
<!-- Creates a bundle containing the contact source interfaces.-->
<jar compress="false" destfile="${bundles.dest}/usersearch.jar"
manifest="${src}/net/java/sip/communicator/plugin/usersearch/usersearch.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/plugin/usersearch"
prefix="net/java/sip/communicator/plugin/usersearch"/>
</jar>
</target>
<!-- BUNDLE-PHONE-NUMBER-CONTACT-SOURCE -->
<target name="bundle-demuxcontactsource">
<!-- Creates a bundle containing the contact source interfaces.-->

@ -196,6 +196,7 @@ felix.auto.start.67= \
reference:file:sc-bundles/plugin-certconfig.jar \
reference:file:sc-bundles/phonenumbercontactsource.jar \
reference:file:sc-bundles/demuxcontactsource.jar \
reference:file:sc-bundles/usersearch.jar \
reference:file:sc-bundles/propertieseditor.jar
# Level 68 is for profiler4j. Either don't use it or change the build.xml file

@ -39,6 +39,7 @@ Export-Package: org.jivesoftware.smack,
org.jivesoftware.smackx.jingle.listeners,
org.jivesoftware.smackx.filetransfer,
org.jivesoftware.smackx.provider,
org.jivesoftware.smackx.search,
org.jivesoftware.smack.sasl,
org.xmlpull.v1,
org.xmlpull.mxp1,

@ -1251,6 +1251,9 @@ plugin.updatechecker.DIALOG_NOUPDATE=Your version is up to date.
plugin.updatechecker.DIALOG_NOUPDATE_TITLE=No new version
plugin.updatechecker.DIALOG_MISSING_UPDATE=Update Installer is missing.
# usersearch
plugin.usersearch.USER_SEARCH=User search
# whiteboard
plugin.whiteboard.TITLE=Whiteboard [Beta]
plugin.whiteboard.MENU_ITEM=Whiteboard

@ -324,12 +324,12 @@ public void actionPerformed(ActionEvent e)
(MetaContact) contactDescriptor.getDescriptor());
}
else if(((SourceContact) contactDescriptor.getDescriptor())
.getContactDetails(OperationSetMultiUserChat.class)
.getContactDetails(OperationSetMultiUserChat.class)
!= null)
{
SourceContact contact = (SourceContact)
contactDescriptor.getDescriptor();
ChatRoomWrapper room
ChatRoomWrapper room
= GuiActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(room != null)
@ -425,11 +425,9 @@ public Component getTreeCellRendererComponent(JTree tree, Object value,
{
UIContactImpl contact
= ((ContactNode) value).getContactDescriptor();
if((contact.getDescriptor() instanceof SourceContact) &&
((SourceContact)contact.getDescriptor())
.getPreferredContactDetail(OperationSetMultiUserChat.class)
!= null)
GuiActivator.getMUCService().isMUCSourceContact((SourceContact)contact.getDescriptor()))
{
setBackground(Constants.CHAT_ROOM_ROW_COLOR);
}
@ -535,7 +533,7 @@ else if (value instanceof GroupNode)
statusIcon = expanded
? openedGroupIcon
: closedGroupIcon;
if(groupItem != treeContactList.getRootUIGroup())
{
this.statusLabel.setIcon(
@ -547,7 +545,7 @@ else if (value instanceof GroupNode)
{
this.statusLabel.setIcon(null);
}
// We have no photo icon for groups.
this.rightLabel.setIcon(null);
this.rightLabel.setText("");
@ -562,8 +560,8 @@ else if (value instanceof GroupNode)
this.initDisplayDetails(groupItem.getDisplayDetails());
this.initButtonsPanel(groupItem);
this.setToolTipText((groupItem.getDescriptor() != null) ?
groupItem.getDescriptor().toString() :
this.setToolTipText((groupItem.getDescriptor() != null) ?
groupItem.getDescriptor().toString() :
groupItem.getDisplayName());
}
@ -846,7 +844,7 @@ private void initButtonsPanel(UIContact uiContact)
if (uiContact.getDescriptor() instanceof MetaContact)
imContact = uiContact.getDefaultContactDetail(
OperationSetBasicInstantMessaging.class);
if(imContact == null)
imContact = uiContact.getDefaultContactDetail(
OperationSetMultiUserChat.class);

@ -42,13 +42,13 @@ public class PresenceFilter
* directly to the contact list without firing events.
*/
private static final int INITIAL_CONTACT_COUNT = 30;
/**
* Preferences for the external contact sources. Lists the type of contact
* contact sources that will be displayed in the filter and the order of the
* Preferences for the external contact sources. Lists the type of contact
* contact sources that will be displayed in the filter and the order of the
* contact sources.
*/
private static Map<Integer, Integer> contactSourcePreferences
private static Map<Integer, Integer> contactSourcePreferences
= new HashMap<Integer, Integer>();
/**
@ -61,7 +61,7 @@ public PresenceFilter()
}
/**
* Initializes the contact source preferences. The preferences are for the
* Initializes the contact source preferences. The preferences are for the
* visibility of the contact source and their order.
*/
private void initContactSourcePreferences()
@ -71,7 +71,7 @@ private void initContactSourcePreferences()
//The chat room sources will be ordered before the meta contact list.
contactSourcePreferences.put(ContactSourceService.CHAT_ROOM_TYPE, 0);
}
/**
* Applies this filter. This filter is applied over the
* <tt>MetaContactListService</tt>.
@ -88,33 +88,33 @@ public void applyFilter(FilterQuery filterQuery)
for(int cssType : contactSourcePreferences.keySet())
{
Iterator<UIContactSource> filterSources
Iterator<UIContactSource> filterSources
= GuiActivator.getContactList().getContactSources(cssType)
.iterator();
while (filterSources.hasNext())
{
UIContactSource filterSource = filterSources.next();
Integer prefValue = contactSourcePreferences.get(cssType);
//We are setting the index from contactSourcePreferences map to
//the contact source. This index is set to reorder the sources
//We are setting the index from contactSourcePreferences map to
//the contact source. This index is set to reorder the sources
//in the contact list.
if(prefValue != null)
filterSource.setContactSourceIndex(prefValue);
ContactSourceService sourceService
= filterSource.getContactSourceService();
ContactQuery contactQuery
ContactQuery contactQuery
= sourceService.createContactQuery(null);
// Add this query to the filterQuery.
filterQuery.addContactQuery(contactQuery);
contactQuery.addContactQueryListener(
GuiActivator.getContactList());
contactQuery.start();
}
}
@ -124,7 +124,7 @@ public void applyFilter(FilterQuery filterQuery)
query.addContactQueryListener(GuiActivator.getContactList());
int resultCount = 0;
addMatching(GuiActivator.getContactListService().getRoot(),
query,
resultCount);
@ -221,8 +221,7 @@ public boolean isMatching(SourceContact contact)
return
isShowOffline
|| contact.getPresenceStatus().isOnline()
|| (contact.getPreferredContactDetail(OperationSetMultiUserChat.class)
!= null);
|| GuiActivator.getMUCService().isMUCSourceContact(contact);
}
/**
@ -284,12 +283,12 @@ private void addMatching( MetaContactGroup metaGroup,
if(isMatching(metaContact))
{
resultCount++;
if (resultCount <= INITIAL_CONTACT_COUNT)
{
UIGroup uiGroup = null;
if (!MetaContactListSource.isRootGroup(metaGroup))
{
synchronized (metaGroup)
@ -309,7 +308,7 @@ private void addMatching( MetaContactGroup metaGroup,
UIContactImpl newUIContact;
synchronized (metaContact)
{
newUIContact
newUIContact
= MetaContactListSource.getUIContact(metaContact);
if (newUIContact == null)
@ -318,7 +317,7 @@ private void addMatching( MetaContactGroup metaGroup,
.createUIContact(metaContact);
}
}
GuiActivator.getContactList().addContact(
newUIContact,
uiGroup,

@ -93,8 +93,7 @@ private void initItems()
add(initCallMenu());
// Only create the menu if the add contact functionality is enabled.
if ((sourceContact.getPreferredContactDetail(
OperationSetMultiUserChat.class) == null)
if (!GuiActivator.getMUCService().isMUCSourceContact(sourceContact)
&& !ConfigurationUtils.isAddContactDisabled())
{
addContactComponent
@ -103,8 +102,8 @@ private void initItems()
if (addContactComponent != null)
add(addContactComponent);
for(JMenuItem item :
for(JMenuItem item :
sourceUIContact.getContactCustomActionMenuItems(true))
{
add(item);

@ -164,7 +164,7 @@ public class TreeContactList
* The container, where this contact list component is added.
*/
private ContactListContainer parentCLContainer;
/**
* The Contacts group instance.
*/
@ -213,7 +213,7 @@ public TreeContactList(ContactListContainer clContainer)
*/
public void contactReceived(ContactReceivedEvent event)
{
final SourceContact sourceContact = event.getContact();
ContactSourceService contactSource
@ -223,7 +223,7 @@ public void contactReceived(ContactReceivedEvent event)
if (sourceUI == null)
return;
UIContact uiContact
= sourceUI.createUIContact(sourceContact);
@ -303,10 +303,10 @@ public void contactChanged(ContactChangedEvent event)
synchronized (uiContact)
{
contactNode = ((UIContactImpl) uiContact).getContactNode();
if (contactNode == null)
return;
nodeChanged(contactNode);
}
@ -324,7 +324,7 @@ public void contactChanged(ContactChangedEvent event)
if (groupNode == null)
return;
}
groupNode.sort(treeModel);
}
}
@ -356,7 +356,7 @@ public void metaContactReceived(MetaContactQueryEvent event)
UIContactImpl newUIContact;
synchronized (metaContact)
{
newUIContact
newUIContact
= MetaContactListSource.getUIContact(metaContact);
if (newUIContact == null)
@ -365,13 +365,13 @@ public void metaContactReceived(MetaContactQueryEvent event)
.createUIContact(metaContact);
}
}
addContact( event.getQuerySource(),
newUIContact,
uiGroup,
true);
}
/**
@ -480,7 +480,7 @@ public void setActiveContact(MetaContact metaContact, boolean isActive)
if (contactNode == null)
return;
}
contactNode.setActive(isActive);
if (isActive)
@ -495,7 +495,7 @@ public void setActiveContact(MetaContact metaContact, boolean isActive)
activeContacts.remove(contactNode);
treeModel.nodeChanged(contactNode);
}
/**
@ -563,22 +563,22 @@ else if (group instanceof UIGroupImpl)
if (groupNode == null)
{
GroupNode parentNode = treeModel.getRoot();
if (isGroupSorted)
groupNode = parentNode.sortedAddContactGroup(contactImpl);
else
groupNode = parentNode.addContactGroup(contactImpl);
if(group.getSourceIndex() < GuiActivator.getContactListService()
.getSourceIndex() && rootUIGroup == null
&& (!(treeModel.getRoot().getChildAfter(groupNode)
.getSourceIndex() && rootUIGroup == null
&& (!(treeModel.getRoot().getChildAfter(groupNode)
instanceof GroupNode)))
{
createMetaUIRootGroup();
}
}
}
}
if (groupNode == null)
@ -591,7 +591,7 @@ else if (group instanceof UIGroupImpl)
ContactNode contactNode = null;
UIContactImpl contactImpl = (UIContactImpl) contact;
synchronized (contactImpl)
{
if(contactImpl.getContactNode() != null)
@ -603,8 +603,8 @@ else if (group instanceof UIGroupImpl)
contactNode = groupNode.sortedAddContact(contactImpl);
else
contactNode = groupNode.addContact(contactImpl);
if(rootUIGroup == null && groupNode == treeModel.getRoot()
if(rootUIGroup == null && groupNode == treeModel.getRoot()
&& treeModel.getRoot().getChildBefore(contactNode) instanceof GroupNode)
{
createMetaUIRootGroup();
@ -623,9 +623,9 @@ else if (group instanceof UIGroupImpl)
*/
public UIGroupImpl getRootUIGroup()
{
return rootUIGroup;
return rootUIGroup;
}
/**
* Creates UI group for the root meta contact group.
*/
@ -633,82 +633,82 @@ private void createMetaUIRootGroup()
{
if(rootUIGroup != null)
return;
rootUIGroup = new UIGroupImpl()
{
private GroupNode groupNode = null;
@Override
public boolean isGroupCollapsed()
{
return true;
}
@Override
public int getSourceIndex()
{
return GuiActivator.getContactListService().getSourceIndex();
}
@Override
public Component getRightButtonMenu()
{
return null;
}
@Override
public UIGroup getParentGroup()
{
return null;
}
@Override
public String getId()
{
return null;
}
@Override
public String getDisplayName()
{
return GuiActivator.getResources()
.getI18NString("service.gui.CONTACTS");
}
@Override
public Object getDescriptor()
{
return null;
}
@Override
public int countOnlineChildContacts()
{
return -1;
}
@Override
public int countChildContacts()
{
return -1;
}
@Override
public void setGroupNode(GroupNode groupNode)
{
this.groupNode = groupNode;
}
@Override
public GroupNode getGroupNode()
{
return groupNode;
}
};
treeModel.getRoot().sortedAddContactGroup(rootUIGroup);
}
/**
* Removes the UI group associated with the root meta contact group.
*/
@ -717,7 +717,7 @@ private void removeMetaUIRootGroup()
if(rootUIGroup == null)
return;
GroupNode parentNode = treeModel.getRoot();
parentNode.removeContactGroup(rootUIGroup);
rootUIGroup = null;
}
@ -824,9 +824,9 @@ public void run()
// Nothing more to do here if we didn't find the parent.
if (parentGroupNode == null)
return;
parentGroupNode.removeContact((UIContactImpl) contact);
// If the parent group is empty remove it.
if (removeEmptyGroup && parentGroupNode.getChildCount() == 0)
{
@ -836,12 +836,12 @@ public void run()
{
parent.removeContactGroup(parentGroup);
}
}
}
if(rootUIGroup != null
&& (treeModel.getRoot().getChildAfter(rootUIGroup.getGroupNode())
if(rootUIGroup != null
&& (treeModel.getRoot().getChildAfter(rootUIGroup.getGroupNode())
instanceof GroupNode || treeModel.getRoot().getChildBefore(
(rootUIGroup).getGroupNode()) == null))
{
@ -886,7 +886,7 @@ public void run()
treeModel.nodeChanged(((UIContactImpl) contact).getContactNode());
}
}
/**
@ -1015,7 +1015,7 @@ public Collection<UIContact> getContacts(final UIGroup group)
return null;
GroupNode groupNode;
if (group == null)
groupNode = treeModel.getRoot();
else
@ -1024,12 +1024,12 @@ public Collection<UIContact> getContacts(final UIGroup group)
{
groupNode = ((UIGroupImpl) group).getGroupNode();
}
}
if (groupNode == null)
return null;
Collection<ContactNode> contactNodes = groupNode.getContacts();
if (contactNodes == null)
@ -1768,12 +1768,12 @@ public void startSelectedContactChat()
.startChat((MetaContact) uiContact.getDescriptor());
}
else if(((SourceContact) uiContact.getDescriptor())
.getContactDetails(OperationSetMultiUserChat.class)
.getContactDetails(OperationSetMultiUserChat.class)
!= null)
{
SourceContact contact = (SourceContact)
uiContact.getDescriptor();
ChatRoomWrapper room
ChatRoomWrapper room
= GuiActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(room != null)
@ -1896,7 +1896,7 @@ private void initContactSources()
else
contactSources.add(extContactSource);
}
}
GuiActivator.bundleContext.addServiceListener(
@ -2123,7 +2123,7 @@ public void contactChanged(ContactChangedEvent event)
ContactSourceService contactSource
= sourceContact.getContactSource();
UIContactSource sourceUI
UIContactSource sourceUI
= getContactSource(contactSource);
if (sourceUI == null)
@ -2132,15 +2132,15 @@ public void contactChanged(ContactChangedEvent event)
UIContact uiContact
= sourceUI.getUIContact(sourceContact);
if(uiContact == null
if(uiContact == null
|| !(uiContact instanceof UIContactImpl))
return;
synchronized (uiContact)
{
ContactNode contactNode
ContactNode contactNode
= ((UIContactImpl) uiContact).getContactNode();
if (contactNode != null)
nodeChanged(contactNode);
}
@ -2151,7 +2151,7 @@ public void contactChanged(ContactChangedEvent event)
contactSource).createContactQuery(filterPattern);
loadedQueries.add(query);
query.start();
// If the image search has been canceled from one of the
@ -2263,7 +2263,9 @@ public static JMenuItem createAddContactMenu(SourceContact sourceContact)
{
JMenuItem addContactComponentTmp = null;
List<ContactDetail> details = sourceContact.getContactDetails();
List<ContactDetail> details
= sourceContact.getContactDetails(
OperationSetPersistentPresence.class);
final String displayName = sourceContact.getDisplayName();
if (details.size() == 1)
@ -2512,11 +2514,11 @@ public void run()
{
if (!(uiContact instanceof UIContactImpl))
return;
setSelectionPath(new TreePath(
((UIContactImpl) uiContact).getContactNode().getPath()));
}
}
/**
@ -2546,7 +2548,7 @@ public void run()
setSelectionPath(new TreePath(
((UIGroupImpl) uiGroup).getGroupNode().getPath()));
}
}
/**

@ -582,6 +582,9 @@ public byte[] getIcon()
@Override
public String getText(SourceContact actionSource)
{
if(!(actionSource instanceof ChatRoomSourceContact))
return "";
if(!name.equals("open_automatically"))
return text;
@ -653,6 +656,8 @@ public boolean isSelected(SourceContact contact)
{
ChatRoomWrapper chatRoomWrapper = MUCActivator.getMUCService()
.findChatRoomWrapperFromSourceContact(contact);
if(chatRoomWrapper == null)
return false;
return chatRoomWrapper.isAutojoin();
}

@ -22,24 +22,24 @@
/**
* The <tt>MUCServiceImpl</tt> class implements the service for the chat rooms.
*
*
* @author Hristo Terezov
*/
public class MUCServiceImpl
extends MUCService
{
/**
* The list of persistent chat rooms.
*/
private final ChatRoomListImpl chatRoomList = new ChatRoomListImpl();
/**
* The <tt>Logger</tt> used by the <tt>MUCServiceImpl</tt> class and its
* instances for logging output.
*/
private static Logger logger = Logger.getLogger(MUCServiceImpl.class);
/**
* Called to accept an incoming invitation. Adds the invitation chat room
* to the list of chat rooms and joins it.
@ -59,27 +59,27 @@ public void acceptInvitation(ChatRoomInvitation invitation)
/**
* Adds a change listener to the <tt>ChatRoomList</tt>.
*
*
* @param l the listener.
*/
public void addChatRoomListChangeListener(ChatRoomListChangeListener l)
{
chatRoomList.addChatRoomListChangeListener(l);
}
/**
* Removes a change listener to the <tt>ChatRoomList</tt>.
*
*
* @param l the listener.
*/
public void removeChatRoomListChangeListener(ChatRoomListChangeListener l)
{
chatRoomList.removeChatRoomListChangeListener(l);
}
/**
* Fires a <tt>ChatRoomListChangedEvent</tt> event.
*
*
* @param chatRoomWrapper the chat room.
* @param eventID the id of the event.
*/
@ -88,7 +88,7 @@ public void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
{
chatRoomList.fireChatRoomListChangedEvent(chatRoomWrapper, eventID);
}
/**
* Joins the given chat room with the given password and manages all the
@ -100,7 +100,7 @@ public void fireChatRoomListChangedEvent( ChatRoomWrapper chatRoomWrapper,
* @param rememberPassword if true the password should be saved.
* @param isFirstAttempt is this the first attempt to join room, used
* to check whether to show some error messages
* @param subject the subject which will be set to the room after the user
* @param subject the subject which will be set to the room after the user
* join successful.
*/
private void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
@ -115,7 +115,7 @@ private void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
if(chatRoom == null)
{
MUCActivator.getAlertUIService().showAlertDialog(
MUCActivator.getResources().getI18NString("service.gui.WARNING"),
MUCActivator.getResources().getI18NString("service.gui.WARNING"),
MUCActivator.getResources().getI18NString(
"service.gui.CHAT_ROOM_NOT_CONNECTED",
new String[]{chatRoomWrapper.getChatRoomName()}));
@ -160,7 +160,7 @@ public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
* @param chatRoomWrapper the chat room to join.
* @param nickName the nickname we choose for the given chat room.
* @param password the password.
* @param subject the subject which will be set to the room after the user
* @param subject the subject which will be set to the room after the user
* join successful.
*/
public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
@ -185,7 +185,7 @@ public void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
.start();
}
/**
* Join chat room.
* @param chatRoomWrapper
@ -230,7 +230,7 @@ public void joinChatRoom( ChatRoom chatRoom,
= chatRoomList.findServerWrapperFromProvider(
chatRoom.getParentProvider());
chatRoomWrapper
chatRoomWrapper
= new ChatRoomWrapperImpl(parentProvider, chatRoom);
chatRoomList.addChatRoom(chatRoomWrapper);
@ -273,19 +273,19 @@ public void joinChatRoom( String chatRoomName,
{
ChatRoomWrapper chatRoomWrapper
= chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
if(chatRoomWrapper == null)
{
ChatRoomProviderWrapper parentProvider
= chatRoomList
.findServerWrapperFromProvider(
chatRoom.getParentProvider());
chatRoomWrapper
chatRoomWrapper
= new ChatRoomWrapperImpl(parentProvider, chatRoom);
chatRoomList.addChatRoom(chatRoomWrapper);
fireChatRoomListChangedEvent(
chatRoomWrapper,
ChatRoomListChangeEvent.CHAT_ROOM_ADDED);
@ -328,7 +328,7 @@ public ChatRoomWrapper createChatRoom(
roomName, protocolProvider, contacts, reason, true, persistent,
isPrivate);
}
/**
* Creates a chat room, by specifying the chat room name, the parent
* protocol provider and eventually, the contacts invited to participate in
@ -387,17 +387,17 @@ public ChatRoomWrapper createChatRoom(
ChatRoom chatRoom = null;
try
{
HashMap<String, Object> roomProperties =
HashMap<String, Object> roomProperties =
new HashMap<String, Object>();
roomProperties.put("isPrivate", isPrivate);
chatRoom = groupChatOpSet.createChatRoom(roomName, roomProperties);
if(join)
{
chatRoom.join();
for(String contact : contacts)
chatRoom.invite(contact, reason);
}
@ -437,7 +437,7 @@ public ChatRoomWrapper createChatRoom(
if(chatRoomWrapper == null)
{
chatRoomWrapper
chatRoomWrapper
= new ChatRoomWrapperImpl(parentProvider, chatRoom);
chatRoomWrapper.setPersistent(persistent);
chatRoomList.addChatRoom(chatRoomWrapper);
@ -467,7 +467,7 @@ public ChatRoomWrapper createPrivateChatRoom(
return this.createChatRoom(
null, protocolProvider, contacts, reason, persistent, true);
}
/**
* Returns existing chat rooms for the given <tt>chatRoomProvider</tt>.
@ -480,7 +480,7 @@ public List<String> getExistingChatRooms(
{
if (chatRoomProvider == null)
return null;
ProtocolProviderService protocolProvider
= chatRoomProvider.getProtocolProvider();
@ -493,7 +493,7 @@ public List<String> getExistingChatRooms(
if (groupChatOpSet == null)
return null;
List<String> chatRooms = null;
try
{
@ -511,10 +511,10 @@ public List<String> getExistingChatRooms(
logger.trace("Failed to obtain existing chat rooms for server: "
+ protocolProvider.getAccountID().getService(), e);
}
return chatRooms;
}
/**
* Rejects the given invitation with the specified reason.
*
@ -529,7 +529,7 @@ public void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
{
multiUserChatOpSet.rejectInvitation(invitation, reason);
}
/**
* Leaves the given chat room.
*
@ -569,7 +569,7 @@ public ChatRoomWrapper leaveChatRoom(ChatRoomWrapper chatRoomWrapper)
chatRoomWrapper.getParentProvider().getProtocolProvider(),
chatRoomWrapper.getChatRoomID(),
GlobalStatusEnum.OFFLINE_STATUS);
return existChatRoomWrapper;
}
@ -601,14 +601,14 @@ private class JoinChatRoomTask
private final String nickName;
private final byte[] password;
private final boolean rememberPassword;
private final boolean isFirstAttempt;
private final String subject;
private ResourceManagementService resources
private ResourceManagementService resources
= MUCActivator.getResources();
JoinChatRoomTask( ChatRoomWrapper chatRoomWrapper,
@ -641,14 +641,14 @@ private class JoinChatRoomTask
}
this.rememberPassword = rememberPassword;
}
JoinChatRoomTask( ChatRoomWrapper chatRoomWrapper,
String nickName,
byte[] password)
{
this(chatRoomWrapper, nickName, password, false, true, null);
}
JoinChatRoomTask( ChatRoomWrapper chatRoomWrapper,
String nickName,
byte[] password,
@ -658,7 +658,7 @@ private class JoinChatRoomTask
}
/**
* @override {@link Thread}{@link #run()} to perform all asynchronous
* @override {@link Thread}{@link #run()} to perform all asynchronous
* tasks.
*/
@Override
@ -791,7 +791,7 @@ else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
new String[]{chatRoomWrapper.getChatRoomName()});
}
if (!SUCCESS.equals(returnCode) &&
if (!SUCCESS.equals(returnCode) &&
!AUTHENTICATION_FAILED.equals(returnCode))
{
MUCActivator.getAlertUIService().showAlertPopup(
@ -804,7 +804,7 @@ else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
{
chatRoomWrapper.savePassword(new String(password));
}
if(subject != null)
{
try
@ -819,9 +819,9 @@ else if(SUBSCRIPTION_ALREADY_EXISTS.equals(returnCode))
}
}
}
/**
* Finds the <tt>ChatRoomWrapper</tt> instance associated with the
* Finds the <tt>ChatRoomWrapper</tt> instance associated with the
* source contact.
* @param contact the source contact.
* @return the <tt>ChatRoomWrapper</tt> instance.
@ -833,17 +833,17 @@ public ChatRoomWrapper findChatRoomWrapperFromSourceContact(
return null;
ChatRoomSourceContact chatRoomContact = (ChatRoomSourceContact) contact;
return chatRoomList.findChatRoomWrapperFromChatRoomID(
chatRoomContact.getChatRoomID(), chatRoomContact.getProvider());
chatRoomContact.getChatRoomID(), chatRoomContact.getProvider());
}
/**
* Finds the <tt>ChatRoomWrapper</tt> instance associated with the
* Finds the <tt>ChatRoomWrapper</tt> instance associated with the
* chat room.
* @param chatRoomID the id of the chat room.
* @param pps the provider of the chat room.
* @return the <tt>ChatRoomWrapper</tt> instance.
*/
public ChatRoomWrapper findChatRoomWrapperFromChatRoomID(String chatRoomID,
public ChatRoomWrapper findChatRoomWrapperFromChatRoomID(String chatRoomID,
ProtocolProviderService pps)
{
return chatRoomList.findChatRoomWrapperFromChatRoomID(chatRoomID, pps);
@ -851,34 +851,34 @@ public ChatRoomWrapper findChatRoomWrapperFromChatRoomID(String chatRoomID,
/**
* Searches for chat room wrapper in chat room list by chat room.
*
*
* @param chatRoom the chat room.
* @param create if <tt>true</tt> and the chat room wrapper is not found new
* chatRoomWrapper is created.
* @return found chat room wrapper or the created chat room wrapper.
*/
@Override
public ChatRoomWrapper getChatRoomWrapperByChatRoom(ChatRoom chatRoom,
public ChatRoomWrapper getChatRoomWrapperByChatRoom(ChatRoom chatRoom,
boolean create)
{
ChatRoomWrapper chatRoomWrapper
= chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
if ((chatRoomWrapper == null) && create)
{
ChatRoomProviderWrapper parentProvider
= chatRoomList.findServerWrapperFromProvider(
chatRoom.getParentProvider());
chatRoomWrapper
chatRoomWrapper
= new ChatRoomWrapperImpl(
parentProvider, chatRoom);
chatRoomList.addChatRoom(chatRoomWrapper);
}
return chatRoomWrapper;
}
/**
* Goes through the locally stored chat rooms list and for each
* {@link ChatRoomWrapper} tries to find the corresponding server stored
@ -901,13 +901,13 @@ public void synchronizeOpSetWithLocalContactList(
{
chatRoomProvider = chatRoomList.addRegisteredChatProvider(protocolProvider);
}
if (chatRoomProvider != null)
{
chatRoomProvider.synchronizeProvider();
}
}
/**
* Returns an iterator to the list of chat room providers.
*
@ -917,7 +917,7 @@ public Iterator<ChatRoomProviderWrapper> getChatRoomProviders()
{
return chatRoomList.getChatRoomProviders();
}
/**
* Removes the given <tt>ChatRoom</tt> from the list of all chat rooms.
*
@ -938,7 +938,7 @@ public void addChatRoomProviderWrapperListener(
{
chatRoomList.addChatRoomProviderWrapperListener(listener);
}
/**
* Removes the ChatRoomProviderWrapperListener to the listener list.
*
@ -949,7 +949,7 @@ public void removeChatRoomProviderWrapperListener(
{
chatRoomList.removeChatRoomProviderWrapperListener(listener);
}
/**
* Returns the <tt>ChatRoomProviderWrapper</tt> that correspond to the
* given <tt>ProtocolProviderService</tt>. If the list doesn't contain a
@ -964,7 +964,7 @@ public ChatRoomProviderWrapper findServerWrapperFromProvider(
{
return chatRoomList.findServerWrapperFromProvider(protocolProvider);
}
/**
* Returns the <tt>ChatRoomWrapper</tt> that correspond to the given
* <tt>ChatRoom</tt>. If the list of chat rooms doesn't contain a
@ -978,10 +978,10 @@ public ChatRoomWrapper findChatRoomWrapperFromChatRoom(ChatRoom chatRoom)
{
return chatRoomList.findChatRoomWrapperFromChatRoom(chatRoom);
}
/**
* Opens a chat window for the chat room.
*
*
* @param room the chat room.
*/
public void openChatRoom(ChatRoomWrapper room)
@ -990,7 +990,7 @@ public void openChatRoom(ChatRoomWrapper room)
{
room = createChatRoom(
room.getChatRoomName(),
room.getParentProvider().getProtocolProvider(),
room.getParentProvider().getProtocolProvider(),
new ArrayList<String>(),"", false, false, true);
// leave the chatroom because getChatRoom().isJoined() returns true
@ -1007,22 +1007,22 @@ public void openChatRoom(ChatRoomWrapper room)
.getParentProvider().getProtocolProvider(), room
.getChatRoomID(), "userNickName");
String subject = null;
if (savedNick == null)
{
String[] joinOptions = ChatRoomJoinOptionsDialog.getJoinOptions(
room.getParentProvider().getProtocolProvider(),
room.getParentProvider().getProtocolProvider(),
room.getChatRoomID(),
getDefaultNickname(
room.getParentProvider().getProtocolProvider()));
savedNick = joinOptions[0];
subject = joinOptions[1];
}
if (savedNick != null)
{
joinChatRoom(room, savedNick, null,
joinChatRoom(room, savedNick, null,
subject);
}
else
@ -1031,7 +1031,7 @@ public void openChatRoom(ChatRoomWrapper room)
MUCActivator.getUIService().openChatRoomWindow(room);
}
/**
* Returns default nickname for chat room based on the given provider.
* @param pps the given protocol provider service
@ -1042,13 +1042,13 @@ public String getDefaultNickname(ProtocolProviderService pps)
final OperationSetServerStoredAccountInfo accountInfoOpSet
= pps.getOperationSet(
OperationSetServerStoredAccountInfo.class);
String displayName = "";
if (accountInfoOpSet != null)
{
displayName = AccountInfoUtils.getDisplayName(accountInfoOpSet);
}
if(displayName == null || displayName.length() == 0)
{
displayName = MUCActivator.getGlobalDisplayDetailsService()
@ -1064,14 +1064,14 @@ public String getDefaultNickname(ProtocolProviderService pps)
}
}
}
return displayName;
}
/**
* Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
* Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
* contact source.
* @return instance of the <tt>ServerChatRoomContactSourceService</tt>
* @return instance of the <tt>ServerChatRoomContactSourceService</tt>
* contact source.
*/
public ContactSourceService getServerChatRoomsContactSourceForProvider(
@ -1079,4 +1079,15 @@ public ContactSourceService getServerChatRoomsContactSourceForProvider(
{
return new ServerChatRoomContactSourceService(pps);
}
/**
* Returns <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
*
* @param contact the contact
* @return <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
*/
public boolean isMUCSourceContact(SourceContact contact)
{
return (contact instanceof ChatRoomSourceContact);
}
}

@ -0,0 +1,279 @@
/*
* 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.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 <tt>UserSearchManager</tt> instance which actually implements the
* user search.
*/
private UserSearchManager searchManager = null;
/**
* The <tt>ProtocolProviderService</tt> 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 <tt>UserSearchProviderListener</tt> listeners which will be
* notified when the provider user search feature is enabled or disabled.
*/
private List<UserSearchProviderListener> listeners
= new ArrayList<UserSearchProviderListener>();
/**
* The property name of the user search service name.
*/
private static final String USER_SEARCH_SERVICE_NAME
= "USER_SEARCH_SERVICE_NAME";
/**
* Constructs new <tt>OperationSetUserSearchJabberImpl</tt> 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 <tt>userSearchEnabled</tt> property and fires
* <tt>UserSearchProviderEvent</tt> 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 <tt>UserSearchProviderEvent</tt> event.
* @param event the event to be fired.
*/
private void fireUserSearchProviderEvent(UserSearchProviderEvent event)
{
List<UserSearchProviderListener> tmpListeners;
synchronized (listeners)
{
tmpListeners = new ArrayList<UserSearchProviderListener>(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<String> serviceNames
= UserSearchManager.getAvailableServiceNames(
provider);
if(!serviceNames.isEmpty())
{
serviceName = serviceNames.get(0);
setUserSearchEnabled(true);
}
else
{
setUserSearchEnabled(false);
}
}
};
}.start();
}
/**
* Creates the <tt>UserSearchManager</tt> instance.
*/
public void createSearchManager()
{
if(searchManager == null)
{
searchManager
= new UserSearchManager(provider.getConnection(), serviceName);
}
}
/**
* Releases the <tt>UserSearchManager</tt> 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<String> 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<Column> columns = data.getColumns();
Iterator<Row> 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<String> result = new ArrayList<String>();
while(rows.hasNext())
{
Row row = rows.next();
result.add((String)row.getValues(jidColumn.getVariable()).next());
}
return result;
}
/**
* Adds <tt>UserSearchProviderListener</tt> 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 <tt>UserSearchProviderListener</tt> instance from the list of
* listeners.
*
* @param l the listener to be removed
*/
public void removeUserSearchProviderListener(UserSearchProviderListener l)
{
synchronized (listeners)
{
listeners.remove(l);
}
}
/**
* Returns <tt>true</tt> if the user search service is enabled.
*
* @return <tt>true</tt> if the user search service is enabled.
*/
public boolean isEnabled()
{
return userSearchEnabled;
}
}

@ -220,6 +220,12 @@ public class ProtocolProviderServiceJabberImpl
private static final String XMPP_DSCP_PROPERTY =
"net.java.sip.communicator.impl.protocol.XMPP_DSCP";
/**
* Indicates if user search is disabled.
*/
private static final String IS_USER_SEARCH_DISABLED_PROPERTY
= "USER_SEARCH_DISABLED";
/**
* Google voice domain name.
*/
@ -1858,6 +1864,14 @@ protected void initialize(String screenname,
addSupportedOperationSet(OperationSetCusaxUtils.class,
opsetCusaxCusaxUtils);
boolean isUserSearchDisabled = accountID.getAccountPropertyBoolean(
IS_USER_SEARCH_DISABLED_PROPERTY, true);
if(!isUserSearchDisabled)
{
addSupportedOperationSet(OperationSetUserSearch.class,
new OperationSetUserSearchJabberImpl(this));
}
isInitialized = true;
}
}

@ -6,6 +6,7 @@
*/
package net.java.sip.communicator.impl.protocol.jabber;
import net.java.sip.communicator.impl.protocol.jabber.extensions.usersearch.*;
import net.java.sip.communicator.util.*;
import org.jivesoftware.smack.packet.*;
@ -139,8 +140,7 @@ public void load()
LastActivity.class);
//<!-- User Search -->
//addProvider("query", "jabber:iq:search",
// org.jivesoftware.smackx.search.UserSearch.Provider.class);
addProvider("query", "jabber:iq:search",UserSearchProvider.class);
//<!-- SharedGroupsInfo -->
//addProvider("sharedgroup", "http://www.jivesoftware.org/protocol/sharedgroup",

@ -0,0 +1,185 @@
/*
* 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.protocol.jabber;
import net.java.sip.communicator.impl.protocol.jabber.extensions.usersearch.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.packet.*;
import java.util.*;
/**
* The <tt>UserSearchManager</tt> implements the user search (XEP-0055). It
* implements searching a contacts by string.
*
* @author Hristo Terezov
*/
public class UserSearchManager {
/**
* The object that represents the connection to the server.
*/
private Connection con;
/**
* Last received search form from the server.
*/
private UserSearchIQ userSearchForm = null;
/**
* The user search service name.
*/
private String searchService;
/**
* Creates a new UserSearchManager.
*
* @param con the Connection to use.
* @param searchService the user search service name.
*/
public UserSearchManager(Connection con, String searchService) {
this.con = con;
this.searchService = searchService;
}
/**
* Returns a list with the available user search service names for a given
* provider.
* @param provider the provider.
* @return a list with the available user search service names for a given
* provider.
*/
public static List<String> getAvailableServiceNames(
ProtocolProviderServiceJabberImpl provider)
{
final List<String> searchServices = new ArrayList<String>();
ScServiceDiscoveryManager discoManager = provider.getDiscoveryManager();
DiscoverItems items;
try
{
items = discoManager.discoverItems(
provider.getConnection().getServiceName());
}
catch (XMPPException e)
{
return searchServices;
}
Iterator<DiscoverItems.Item> iter = items.getItems();
while (iter.hasNext())
{
DiscoverItems.Item item = iter.next();
try
{
DiscoverInfo info;
info = discoManager.discoverInfo(item.getEntityID());
if (info.containsFeature("jabber:iq:search")
&& !info.containsFeature("http://jabber.org/protocol/muc"))
{
searchServices.add(item.getEntityID());
}
}
catch (Exception e) {
continue;
}
}
return searchServices;
}
/**
* Returns the form to fill out to perform a search.
*
* @return the form to fill out to perform a search.
* @throws XMPPException thrown if a server error has occurred.
*/
private void getSearchForm() throws XMPPException {
UserSearchIQ search = new UserSearchIQ();
search.setType(IQ.Type.GET);
search.setTo(searchService);
PacketCollector collector = con.createPacketCollector(
new PacketIDFilter(search.getPacketID()));
con.sendPacket(search);
IQ response = (IQ) collector.nextResult(
SmackConfiguration.getPacketReplyTimeout());
// Cancel the collector.
collector.cancel();
if (response == null) {
throw new XMPPException("No response from server on status set.");
}
if (response.getError() != null) {
throw new XMPPException(response.getError());
}
userSearchForm = (UserSearchIQ)response;
}
/**
* Performs user search for the searched string.
*
* @param searchedString
* @return the <tt>ReportedData</tt> instance which represents the search
* results.
* @throws XMPPException thrown if a server error has occurred.
*/
public ReportedData searchForString(String searchedString) throws XMPPException
{
if(userSearchForm == null)
getSearchForm();
UserSearchIQ search = new UserSearchIQ();
search.setType(IQ.Type.SET);
search.setTo(searchService);
Form form = userSearchForm.getAnswerForm();
if(form != null)
{
Iterator<FormField> fields = form.getFields();
while (fields.hasNext())
{
FormField formField = fields.next();
if(formField.getType().equals(FormField.TYPE_BOOLEAN))
{
form.setAnswer(formField.getVariable(), true);
}
else if(formField.getType().equals(FormField.TYPE_TEXT_SINGLE))
{
form.setAnswer(formField.getVariable(), searchedString);
}
}
search.setForm(form.getDataFormToSend());
}
else
{
for(String field : userSearchForm.getFields())
search.addField(field, searchedString);
}
PacketCollector collector = con.createPacketCollector(
new PacketIDFilter(search.getPacketID()));
con.sendPacket(search);
UserSearchIQ response = (UserSearchIQ) collector.nextResult(
SmackConfiguration.getPacketReplyTimeout());
// Cancel the collector.
collector.cancel();
if (response == null) {
throw new XMPPException("No response from server on status set.");
}
if (response.getError() != null) {
throw new XMPPException(response.getError());
}
return response.getData();
}
}

@ -0,0 +1,135 @@
/*
* 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.protocol.jabber.extensions.usersearch;
import java.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.util.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.packet.*;
/**
* Implements the <tt>IQ</tt> packets for user search (XEP-0055)
*
* @author Hristo Terezov
*/
public class UserSearchIQ extends IQ {
/**
* This field represents the result of the search.
*/
private ReportedData data;
/**
* This map stores the supported fields that are not defined in the data
* form and their values.
*/
private Map<String, String> simpleFieldsNames
= new HashMap<String, String>();
@Override
public String getChildElementXML() {
StringBuilder buf = new StringBuilder();
buf.append("<query xmlns=\"jabber:iq:search\">");
if(getExtension("x", "jabber:x:data") != null)
{
buf.append(getExtensionsXML());
}
else
{
buf.append(getItemsToSearch());
}
buf.append("</query>");
return buf.toString();
}
/**
* Sets the <tt>data</tt> property of the class.
* @param data the data to be set.
*/
public void setData(ReportedData data)
{
this.data = data;
}
/**
* Returns the <tt>data</tt> property of the class.
* @return
*/
public ReportedData getData()
{
ReportedData data = ReportedData.getReportedDataFrom(this);
if(data == null)
return this.data;
return data;
}
/**
* Adds filter field to the <tt>IQ</tt> packet and value for the field.
* @param field the field name.
* @param value the value of the field.
*/
public void addField(String field, String value)
{
simpleFieldsNames.put(field, value);
}
/**
* Returns XML string with the fields that are not included in the data form
* @return XML string with the fields that are not included in the data form
*/
private String getItemsToSearch() {
StringBuilder buf = new StringBuilder();
if (simpleFieldsNames.isEmpty()) {
return "";
}
for (String name : simpleFieldsNames.keySet())
{
String value = simpleFieldsNames.get(name);
if (value != null && value.trim().length() > 0) {
buf.append("<").append(name).append(">")
.append(StringUtils.escapeForXML(value)).append("</")
.append(name).append(">");
}
}
return buf.toString();
}
/**
* Returns the names of the fields that are not included in the data form.
* @return the field names.
*/
public Set<String> getFields()
{
return simpleFieldsNames.keySet();
}
/**
* Creates and returns answer form.
* @return the answer form.
*/
public Form getAnswerForm()
{
Form form = Form.getFormFrom(this);
if(form == null)
return null;
return form.createAnswerForm();
}
/**
* Sets data form in the <tt>IQ</tt> packet.
* @param form the form to be set.
*/
public void setForm(DataForm form)
{
addExtension(form);
}
}

@ -0,0 +1,145 @@
/*
* 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.protocol.jabber.extensions.usersearch;
import java.util.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.jivesoftware.smack.util.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.ReportedData.*;
import org.xmlpull.v1.*;
/**
* Internal Search service Provider. It parses the <tt>UserSeachIQ</tt> packets.
*/
public class UserSearchProvider implements IQProvider
{
public IQ parseIQ(XmlPullParser parser) throws Exception
{
UserSearchIQ search = new UserSearchIQ();
boolean done = false;
while (!done)
{
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG
&& parser.getName().equals("item"))
{
search.setData(parseItems(parser));
return search;
}
else if (eventType == XmlPullParser.START_TAG
&& parser.getName().equals("instructions"))
{
continue;
}
else if (eventType == XmlPullParser.START_TAG
&& !parser.getNamespace().equals("jabber:x:data"))
{
search.addField(parser.getName(), null);
}
else if (eventType == XmlPullParser.START_TAG
&& parser.getNamespace().equals("jabber:x:data"))
{
// Otherwise, it must be a packet extension.
search.addExtension(PacketParserUtils.parsePacketExtension(
parser.getName(), parser.getNamespace(), parser));
}
else if (eventType == XmlPullParser.END_TAG)
{
if (parser.getName().equals("query"))
done = true;
}
}
return search;
}
/**
* Parses the items from the result packet.
* @param parser the parser.
* @return <tt>ReportedData</tt> instance with the search results.
* @throws Exception if parser error occurred.
*/
protected ReportedData parseItems(XmlPullParser parser) throws Exception
{
ReportedData data = new ReportedData();
data.addColumn(
new ReportedData.Column("JID", "jid", FormField.TYPE_JID_SINGLE));
boolean done = false;
List<ReportedData.Field> fields
= new ArrayList<ReportedData.Field>();
while (!done)
{
if (parser.getAttributeCount() > 0)
{
String jid = parser.getAttributeValue("", "jid");
List<String> valueList = new ArrayList<String>();
valueList.add(jid);
ReportedData.Field field = new ReportedData.Field("jid", valueList);
fields.add(field);
}
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG
&& parser.getName().equals("item"))
{
fields = new ArrayList<ReportedData.Field>();
}
else if (eventType == XmlPullParser.END_TAG
&& parser.getName().equals("item"))
{
ReportedData.Row row = new ReportedData.Row(fields);
data.addRow(row);
}
else if (eventType == XmlPullParser.START_TAG)
{
String name = parser.getName();
String value = parser.nextText();
List<String> valueList = new ArrayList<String>();
valueList.add(value);
ReportedData.Field field
= new ReportedData.Field(name, valueList);
fields.add(field);
boolean exists = false;
Iterator<Column> cols = data.getColumns();
while (cols.hasNext())
{
ReportedData.Column column = cols.next();
if (column.getVariable().equals(name))
exists = true;
}
// Column name should be the same
if (!exists)
{
ReportedData.Column column = new ReportedData.Column(
name, name, "text-single");
data.addColumn(column);
}
}
else if (eventType == XmlPullParser.END_TAG)
{
if (parser.getName().equals("query"))
done = true;
}
}
return data;
}
}

@ -0,0 +1,376 @@
/*
* 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.plugin.usersearch;
import java.util.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.resources.ResourceManagementService;
import org.osgi.framework.*;
/**
* Activates the user search plugin which includes the user search contact
* source.
*
* @author Hristo Terezov
*/
public class UserSearchActivator
implements BundleActivator
{
/**
* List with the available protocol providers that may support user search.
*/
private static LinkedList<ProtocolProviderService> userSearchProviders;
/**
* The bundle context.
*/
public static BundleContext bundleContext;
/**
* A listener for
*/
private static UserSearchProviderStateListener userSeachListener = null;
/**
* A list with providers that support user search.
*/
private static LinkedList<ProtocolProviderService> supportedProviders
= new LinkedList<ProtocolProviderService>();
/**
* A list of listeners that will be notified about adding and removing
* providers that support user search.
*/
private static LinkedList<UserSearchSupportedProviderListener> listeners
= new LinkedList<UserSearchSupportedProviderListener>();
/**
* The <tt>ServiceRegistration</tt> instance for the contact source.
*/
private static ServiceRegistration contactSourceRegistration = null;
/**
* The <tt>Logger</tt> used by the
* <tt>UserSearchActivator</tt> class for logging output.
*/
private static Logger logger = Logger.getLogger(UserSearchActivator.class);
/**
* Contact source instance.
*/
private static UserSearchContactSource userSearchContactSource = null;
/**
* The resource service.
*/
private static ResourceManagementService resources = null;
/**
* Initializes a list of all currently providers and a list with the
* providers that support user search.
*/
public static void initUserSearchProviders()
{
if (userSearchProviders != null)
return;
userSearchProviders = new LinkedList<ProtocolProviderService>();
bundleContext.addServiceListener(new ProtocolProviderRegListener());
ServiceReference[] serRefs = null;
try
{
// get all registered provider factories
serRefs
= bundleContext.getServiceReferences(
ProtocolProviderFactory.class.getName(),
null);
}
catch (InvalidSyntaxException e)
{
logger.error("LoginManager : " + e);
}
if (serRefs != null)
{
for (ServiceReference serRef : serRefs)
{
ProtocolProviderFactory providerFactory
= (ProtocolProviderFactory)
bundleContext.getService(serRef);
ProtocolProviderService protocolProvider;
for (AccountID accountID
: providerFactory.getRegisteredAccounts())
{
serRef = providerFactory.getProviderForAccount(accountID);
protocolProvider
= (ProtocolProviderService) bundleContext
.getService(serRef);
handleProviderAdded(protocolProvider);
}
}
}
return;
}
/**
* Returns the list of providers that support user search.
* @return the list of providers that support user search.
*/
public static LinkedList<ProtocolProviderService> getSupportedProviders()
{
return supportedProviders;
}
/**
* Adds new <tt>UserSearchSupportedProviderListener</tt> to the list of
* listeners.
* @param listener the listener to be added.
*/
public static void addUserSearchSupportedProviderListener(
UserSearchSupportedProviderListener listener)
{
synchronized (listeners)
{
if(!listeners.contains(listener))
listeners.add(listener);
}
}
/**
* Removes <tt>UserSearchSupportedProviderListener</tt> from the list of
* listeners.
* @param listener the listener to be removed.
*/
public static void removeUserSearchSupportedProviderListener(
UserSearchSupportedProviderListener listener)
{
synchronized (listeners)
{
listeners.remove(listener);
}
}
/**
* Listens for <tt>ProtocolProviderService</tt> registrations.
*/
private static class ProtocolProviderRegListener
implements ServiceListener
{
public void serviceChanged(ServiceEvent event)
{
ServiceReference serviceRef = event.getServiceReference();
// if the event is caused by a bundle being stopped, we don't want to
// know
if (serviceRef.getBundle().getState() == Bundle.STOPPING)
{
return;
}
Object service = bundleContext.getService(serviceRef);
// we don't care if the source service is not a protocol provider
if (!(service instanceof ProtocolProviderService))
{
return;
}
switch (event.getType())
{
case ServiceEvent.REGISTERED:
handleProviderAdded((ProtocolProviderService) service);
break;
case ServiceEvent.UNREGISTERING:
handleProviderRemoved((ProtocolProviderService) service);
break;
}
}
}
/**
* Handles the registration of a new <tt>ProtocolProviderService</tt>. Adds
* the given <tt>protocolProvider</tt> to the list of queried providers.
*
* @param protocolProvider the <tt>ProtocolProviderService</tt> to add
*/
private static void handleProviderAdded(
ProtocolProviderService protocolProvider)
{
if (protocolProvider.getOperationSet(
OperationSetServerStoredContactInfo.class) != null
&& !userSearchProviders.contains(protocolProvider))
{
OperationSetUserSearch opSet
= protocolProvider.getOperationSet(OperationSetUserSearch.class);
if(opSet == null)
return;
if(userSeachListener == null)
userSeachListener = new UserSearchProviderStateListener();
opSet.addUserSearchProviderListener(userSeachListener);
if(opSet.isEnabled())
addSupportedProvider(protocolProvider);
userSearchProviders.add(protocolProvider);
}
}
/**
* Handles the un-registration of a <tt>ProtocolProviderService</tt>.
* Removes the given <tt>protocolProvider</tt> from the list of queried
* providers.
*
* @param protocolProvider the <tt>ProtocolProviderService</tt> to remove
*/
private static void handleProviderRemoved(
ProtocolProviderService protocolProvider)
{
if (userSearchProviders.contains(protocolProvider))
{
userSearchProviders.remove(protocolProvider);
removeSupportedProvider(protocolProvider);
if(userSeachListener == null)
return;
OperationSetUserSearch opSet
= protocolProvider.getOperationSet(OperationSetUserSearch.class);
if(opSet == null)
return;
opSet.removeUserSearchProviderListener(userSeachListener);
}
}
/**
* Adds provider to the list of providers that support user search.
* @param provider the provider to be added
*/
private static void addSupportedProvider(ProtocolProviderService provider)
{
if(!supportedProviders.contains(provider))
{
supportedProviders.add(provider);
LinkedList<UserSearchSupportedProviderListener> tmpListeners;
synchronized (listeners)
{
tmpListeners
= new LinkedList<UserSearchSupportedProviderListener>(
listeners);
}
for(UserSearchSupportedProviderListener l : tmpListeners)
{
l.providerAdded(provider);
}
if(supportedProviders.size() == 1)
{
if(userSearchContactSource == null)
userSearchContactSource = new UserSearchContactSource();
//register contact source
contactSourceRegistration = bundleContext.registerService(
ContactSourceService.class.getName(),
userSearchContactSource ,
null);
}
}
}
/**
* Removes provider from the list of providers that support user search.
* @param provider the procider to be removed.
*/
private static void removeSupportedProvider(
ProtocolProviderService provider)
{
if(supportedProviders.contains(provider))
{
supportedProviders.remove(provider);
for(UserSearchSupportedProviderListener l : listeners)
{
l.providerRemoved(provider);
}
if(supportedProviders.isEmpty()
&& contactSourceRegistration != null)
{
contactSourceRegistration.unregister();
contactSourceRegistration = null;
}
}
}
@Override
public void start(BundleContext context) throws Exception
{
bundleContext = context;
initUserSearchProviders();
}
@Override
public void stop(BundleContext context) throws Exception
{
userSeachListener = null;
userSearchProviders.clear();
supportedProviders.clear();
listeners.clear();
contactSourceRegistration = null;
userSearchContactSource = null;
}
/**
* Returns a reference to the ResourceManagementService implementation
* currently registered in the bundle context or null if no such
* implementation was found.
*
* @return a reference to a ResourceManagementService implementation
* currently registered in the bundle context or null if no such
* implementation was found.
*/
public static ResourceManagementService getResources()
{
if (resources == null)
{
resources
= ServiceUtils.getService(
bundleContext, ResourceManagementService.class);
}
return resources;
}
/**
* Listens for added or removed providers that support user search.
*/
private static class UserSearchProviderStateListener
implements UserSearchProviderListener
{
@Override
public void onUserSearchProviderEvent(UserSearchProviderEvent event)
{
if(event.getType() == UserSearchProviderEvent.PROVIDER_ADDED)
{
addSupportedProvider(event.getProvider());
}
else if(event.getType() == UserSearchProviderEvent.PROVIDER_REMOVED)
{
removeSupportedProvider(event.getProvider());
}
}
}
}

@ -0,0 +1,64 @@
/*
* 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.plugin.usersearch;
import net.java.sip.communicator.service.contactsource.*;
/**
* The user search contact source.
*
* @author Hristo Terezov
*/
public class UserSearchContactSource
implements ContactSourceService
{
/**
* The time to wait before actually start the searching. If the query is
* canceled before the timeout the query won't be started.
*/
public static final long QUERY_DELAY = 500;
/**
* Returns the type of this contact source.
*
* @return the type of this contact source
*/
public int getType()
{
return SEARCH_TYPE;
}
@Override
public String getDisplayName()
{
return UserSearchActivator.getResources().getI18NString(
"plugin.usersearch.USER_SEARCH");
}
@Override
public ContactQuery createContactQuery(String queryString)
{
return createContactQuery(queryString, -1);
}
@Override
public ContactQuery createContactQuery(String queryString, int contactCount)
{
if(queryString == null)
queryString = "";
UserSearchQuery query = new UserSearchQuery(queryString, this);
return query;
}
@Override
public int getIndex()
{
return 0;
}
}

@ -0,0 +1,295 @@
/*
* 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.plugin.usersearch;
import java.util.*;
import java.util.regex.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.protocol.*;
/**
* The <tt>UserSearchQuery</tt> is a query over
* <tt>UserSearchContactSource</tt>.
*/
public class UserSearchQuery
extends AsyncContactQuery<ContactSourceService>
implements UserSearchSupportedProviderListener
{
/**
* The query string.
*/
private String queryString;
/**
* A list with the found contacts.
*/
private List<UserSearchContact> contacts
= new LinkedList<UserSearchContact>();
/**
* A list of providers that are already displayed.
*/
private List<ProtocolProviderService> displayedProviders
= new LinkedList<ProtocolProviderService>();
/**
* The number of the listeners added to the query.
*/
private int contactQueryListenersCount = 0;
/**
* Creates an instance of <tt>ChatRoomQuery</tt> by specifying
* the parent contact source, the query string to match and the maximum
* result contacts to return.
*
* @param queryString the query string to match
* @param contactSource the parent contact source
*/
public UserSearchQuery(String queryString,
UserSearchContactSource contactSource)
{
super(contactSource,
Pattern.compile(queryString, Pattern.CASE_INSENSITIVE
| Pattern.LITERAL), true);
this.queryString = queryString;
}
@Override
protected void run()
{
try
{
Thread.sleep(UserSearchContactSource.QUERY_DELAY);
}
catch (InterruptedException e)
{ }
if(getStatus() == QUERY_CANCELED)
return;
for(ProtocolProviderService provider :
UserSearchActivator.getSupportedProviders())
{
providerAdded(provider);
}
}
/**
* Handles provider addition.
*
* @param provider the provider that was added.
*/
public void providerAdded(ProtocolProviderService provider)
{
synchronized (displayedProviders)
{
if(displayedProviders.contains(provider))
return;
displayedProviders.add(provider);
}
OperationSetUserSearch opSetUserSearch
= provider.getOperationSet(
OperationSetUserSearch.class);
if(opSetUserSearch == null)
{
return;
}
opSetUserSearch.createSearchManager();
List<String> jidList = opSetUserSearch.search(queryString);
if(jidList == null || jidList.isEmpty())
return;
List<Class<? extends OperationSet>> supportedOpSets
= new ArrayList<Class<? extends OperationSet>>(1);
supportedOpSets.add(OperationSetPersistentPresence.class);
ContactDetail detail = new ContactDetail(queryString);
for(String jid : jidList)
{
List<ContactDetail> contactDetails
= new LinkedList<ContactDetail>();
ContactDetail jidDetail = new ContactDetail(jid);
jidDetail.setSupportedOpSets(supportedOpSets);
contactDetails.add(jidDetail);
contactDetails.add(detail);
UserSearchContact contact
= new UserSearchContact(
this,
getContactSource(),
jid,
contactDetails,
provider);
contact.setContactAddress(jid);
synchronized (contacts)
{
contacts.add(contact);
}
fireContactReceived(contact);
}
}
/**
* Handles provider removal.
*
* @param provider the provider that was removed.
*/
public void providerRemoved(ProtocolProviderService provider)
{
synchronized (displayedProviders)
{
displayedProviders.remove(provider);
}
OperationSetUserSearch opSetUserSearch
= provider.getOperationSet(
OperationSetUserSearch.class);
if(opSetUserSearch == null)
return;
opSetUserSearch.removeSearchManager();
List<UserSearchContact> tmpContacts;
synchronized (contacts)
{
tmpContacts = new LinkedList<UserSearchContact>(contacts);
}
for(UserSearchContact contact : tmpContacts)
{
if(contact.getProvider().equals(provider))
{
synchronized (contacts)
{
contacts.remove(contact);
}
fireContactRemoved(contact);
}
}
}
/**
* Releases the resources of the query.
*/
private void dispose()
{
UserSearchActivator.removeUserSearchSupportedProviderListener(this);
synchronized (contacts)
{
contacts.clear();
}
synchronized (displayedProviders)
{
displayedProviders.clear();
}
}
/**
* Cancels this <tt>ContactQuery</tt>.
*
* @see ContactQuery#cancel()
*/
public void cancel()
{
dispose();
super.cancel();
}
/**
* If query has status changed to cancel, let's clear listeners.
* @param status {@link ContactQuery#QUERY_CANCELED},
* {@link ContactQuery#QUERY_COMPLETED}
*/
public void setStatus(int status)
{
if(status == QUERY_CANCELED)
dispose();
super.setStatus(status);
}
@Override
public void addContactQueryListener(ContactQueryListener l)
{
super.addContactQueryListener(l);
contactQueryListenersCount++;
if(contactQueryListenersCount == 1)
{
UserSearchActivator.addUserSearchSupportedProviderListener(this);
}
}
@Override
public void removeContactQueryListener(ContactQueryListener l)
{
super.removeContactQueryListener(l);
contactQueryListenersCount--;
if(contactQueryListenersCount == 0)
{
dispose();
}
}
/**
* A specific user search source contact.
*/
private class UserSearchContact
extends SortedGenericSourceContact
{
/**
* The provider associated with the contact.
*/
private ProtocolProviderService provider;
public UserSearchContact(ContactQuery parentQuery,
ContactSourceService cSourceService, String displayName,
List<ContactDetail> contactDetails,
ProtocolProviderService provider)
{
super(parentQuery, cSourceService, displayName, contactDetails);
this.provider = provider;
}
/**
* Returns the provider associated with the contact.
* @return the provider associated with the contact.
*/
public ProtocolProviderService getProvider()
{
return provider;
}
}
@Override
public List<SourceContact> getQueryResults()
{
List<SourceContact> queryResults;
synchronized (contacts)
{
queryResults = new LinkedList<SourceContact>(contacts);
}
return queryResults;
}
@Override
public int getQueryResultCount()
{
synchronized (contacts)
{
return contacts.size();
}
}
}

@ -0,0 +1,31 @@
/*
* 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.plugin.usersearch;
import net.java.sip.communicator.service.protocol.*;
/**
* A interface for a listener that will be notified when providers that support
* user search are added or removed.
* @author Hristo Terezov
*/
public interface UserSearchSupportedProviderListener
{
/**
* Handles provider addition.
*
* @param provider the provider that was added.
*/
public void providerAdded(ProtocolProviderService provider);
/**
* Handles provider removal.
*
* @param provider the provider that was removed.
*/
public void providerRemoved(ProtocolProviderService provider);
}

@ -0,0 +1,12 @@
Bundle-Activator: net.java.sip.communicator.plugin.usersearch.UserSearchActivator
Bundle-Name: User search contact source
Bundle-Description: User search contact source
Bundle-Vendor: jitsi.org
Bundle-Version: 0.0.1
Bundle-SymbolicName: net.java.sip.communicator.plugin.usersearch
Import-Package: org.osgi.framework,
net.java.sip.communicator.service.contactsource,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.util,
org.jitsi.service.resources

@ -13,47 +13,47 @@
import net.java.sip.communicator.util.*;
/**
* The MUC service provides interface for the chat rooms. It connects the GUI
* The MUC service provides interface for the chat rooms. It connects the GUI
* with the protcol.
*
*
* @author Hristo Terezov
*/
public abstract class MUCService
{
/**
* The value for chat room configuration property to open automatically on
* activity
* The value for chat room configuration property to open automatically on
* activity
*/
public static String OPEN_ON_ACTIVITY = "on_activity";
/**
* The value for chat room configuration property to open automatically on
* message
* The value for chat room configuration property to open automatically on
* message
*/
public static String OPEN_ON_MESSAGE = "on_message";
/**
* The value for chat room configuration property to open automatically on
* important messages.
* The value for chat room configuration property to open automatically on
* important messages.
*/
public static String OPEN_ON_IMPORTANT_MESSAGE = "on_important_message";
/**
* Map for the auto open configuration values and their text representation
*/
public static Map<String, String> autoOpenConfigValuesTexts
= new HashMap<String, String>();
static
{
autoOpenConfigValuesTexts.put(OPEN_ON_ACTIVITY,
autoOpenConfigValuesTexts.put(OPEN_ON_ACTIVITY,
"service.gui.OPEN_ON_ACTIVITY");
autoOpenConfigValuesTexts.put(OPEN_ON_MESSAGE,
autoOpenConfigValuesTexts.put(OPEN_ON_MESSAGE,
"service.gui.OPEN_ON_MESSAGE");
autoOpenConfigValuesTexts.put(OPEN_ON_IMPORTANT_MESSAGE,
autoOpenConfigValuesTexts.put(OPEN_ON_IMPORTANT_MESSAGE,
"service.gui.OPEN_ON_IMPORTANT_MESSAGE");
}
/**
* Sets chat room open automatically property
* @param pps the provider
@ -69,7 +69,7 @@ public static void setChatRoomAutoOpenOption(
pps,
chatRoomId, "openAutomatically", value);
}
/**
* Returns the value of the chat room open automatically property
* @param pps the provider
@ -87,13 +87,13 @@ public static String getChatRoomAutoOpenOption(
/**
* Fires a <tt>ChatRoomListChangedEvent</tt> event.
*
*
* @param chatRoomWrapper the chat room.
* @param eventID the id of the event.
*/
public abstract void fireChatRoomListChangedEvent(
ChatRoomWrapper chatRoomWrapper, int eventID);
/**
* Joins the given chat room with the given password and manages all the
* exceptions that could occur during the join process.
@ -101,12 +101,12 @@ public abstract void fireChatRoomListChangedEvent(
* @param chatRoomWrapper the chat room to join.
* @param nickName the nickname we choose for the given chat room.
* @param password the password.
* @param subject the subject which will be set to the room after the user
* @param subject the subject which will be set to the room after the user
* join successful.
*/
public abstract void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
String nickName, byte[] password, String subject);
/**
* Creates a chat room, by specifying the chat room name, the parent
* protocol provider and eventually, the contacts invited to participate in
@ -122,9 +122,9 @@ public abstract void joinChatRoom( ChatRoomWrapper chatRoomWrapper,
public abstract ChatRoomWrapper createChatRoom(String roomName,
ProtocolProviderService protocolProvider, Collection<String> contacts,
String reason, boolean persistent);
/**
* Creates a private chat room, by specifying the parent
* protocol provider and eventually, the contacts invited to participate in
@ -139,8 +139,8 @@ public abstract ChatRoomWrapper createChatRoom(String roomName,
public abstract ChatRoomWrapper createPrivateChatRoom(
ProtocolProviderService protocolProvider, Collection<String> contacts,
String reason, boolean persistent);
/**
* Creates a chat room, by specifying the chat room name, the parent
* protocol provider and eventually, the contacts invited to participate in
@ -158,7 +158,7 @@ public abstract ChatRoomWrapper createPrivateChatRoom(
public abstract ChatRoomWrapper createChatRoom(String roomName,
ProtocolProviderService protocolProvider, Collection<String> contacts,
String reason, boolean join, boolean persistent, boolean isPrivate);
/**
* Joins the room with the given name though the given chat room provider.
*
@ -167,7 +167,7 @@ public abstract ChatRoomWrapper createChatRoom(String roomName,
*/
public abstract void joinChatRoom( String chatRoomName,
ChatRoomProviderWrapper chatRoomProvider);
/**
* Returns existing chat rooms for the given <tt>chatRoomProvider</tt>.
* @param chatRoomProvider the <tt>ChatRoomProviderWrapper</tt>, which
@ -176,8 +176,8 @@ public abstract void joinChatRoom( String chatRoomName,
*/
public abstract List<String> getExistingChatRooms(
ChatRoomProviderWrapper chatRoomProvider);
/**
* Called to accept an incoming invitation. Adds the invitation chat room
* to the list of chat rooms and joins it.
@ -185,7 +185,7 @@ public abstract List<String> getExistingChatRooms(
* @param invitation the invitation to accept.
*/
public abstract void acceptInvitation(ChatRoomInvitation invitation);
/**
* Rejects the given invitation with the specified reason.
*
@ -197,7 +197,7 @@ public abstract List<String> getExistingChatRooms(
public abstract void rejectInvitation( OperationSetMultiUserChat multiUserChatOpSet,
ChatRoomInvitation invitation,
String reason);
/**
* Determines whether a specific <code>ChatRoom</code> is private i.e.
* represents a one-to-one conversation which is not a channel. Since the
@ -229,7 +229,7 @@ public static boolean isPrivate(ChatRoom chatRoom)
}
return false;
}
/**
* Leaves the given chat room.
*
@ -239,18 +239,18 @@ public static boolean isPrivate(ChatRoom chatRoom)
public abstract ChatRoomWrapper leaveChatRoom(ChatRoomWrapper chatRoomWrapper);
/**
* Finds <tt>ChatRoomWrapper</tt> instance associated with the given source
* Finds <tt>ChatRoomWrapper</tt> instance associated with the given source
* contact.
* @param contact the contact.
* @return <tt>ChatRoomWrapper</tt> instance associated with the given
* @return <tt>ChatRoomWrapper</tt> instance associated with the given
* source contact.
*/
public abstract ChatRoomWrapper findChatRoomWrapperFromSourceContact(
SourceContact contact);
/**
* Searches for chat room wrapper in chat room list by chat room.
*
*
* @param chatRoom the chat room.
* @param create if <tt>true</tt> and the chat room wrapper is not found new
* chatRoomWrapper is created.
@ -258,7 +258,7 @@ public abstract ChatRoomWrapper findChatRoomWrapperFromSourceContact(
*/
public abstract ChatRoomWrapper getChatRoomWrapperByChatRoom(
ChatRoom chatRoom, boolean create);
/**
* Returns the multi user chat operation set for the given protocol provider.
*
@ -277,7 +277,7 @@ public static OperationSetMultiUserChat getMultiUserChatOpSet(
? (OperationSetMultiUserChat) opSet
: null;
}
/**
* Goes through the locally stored chat rooms list and for each
* {@link ChatRoomWrapper} tries to find the corresponding server stored
@ -292,21 +292,21 @@ public static OperationSetMultiUserChat getMultiUserChatOpSet(
public abstract void synchronizeOpSetWithLocalContactList(
ProtocolProviderService protocolProvider,
final OperationSetMultiUserChat opSet);
/**
* Returns an iterator to the list of chat room providers.
*
* @return an iterator to the list of chat room providers.
*/
public abstract Iterator<ChatRoomProviderWrapper> getChatRoomProviders();
/**
* Removes the given <tt>ChatRoom</tt> from the list of all chat rooms.
*
* @param chatRoomWrapper the <tt>ChatRoomWrapper</tt> to remove
*/
public abstract void removeChatRoom(ChatRoomWrapper chatRoomWrapper);
/**
* Adds a ChatRoomProviderWrapperListener to the listener list.
*
@ -314,7 +314,7 @@ public abstract void synchronizeOpSetWithLocalContactList(
*/
public abstract void addChatRoomProviderWrapperListener(
ChatRoomProviderWrapperListener listener);
/**
* Removes the ChatRoomProviderWrapperListener to the listener list.
*
@ -322,7 +322,7 @@ public abstract void addChatRoomProviderWrapperListener(
*/
public abstract void removeChatRoomProviderWrapperListener(
ChatRoomProviderWrapperListener listener);
/**
* Returns the <tt>ChatRoomProviderWrapper</tt> that correspond to the
* given <tt>ProtocolProviderService</tt>. If the list doesn't contain a
@ -334,7 +334,7 @@ public abstract void removeChatRoomProviderWrapperListener(
*/
public abstract ChatRoomProviderWrapper findServerWrapperFromProvider(
ProtocolProviderService protocolProvider);
/**
* Returns the <tt>ChatRoomWrapper</tt> that correspond to the given
* <tt>ChatRoom</tt>. If the list of chat rooms doesn't contain a
@ -346,14 +346,14 @@ public abstract ChatRoomProviderWrapper findServerWrapperFromProvider(
*/
public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoom(
ChatRoom chatRoom);
/**
* Opens a chat window for the chat room.
*
*
* @param room the chat room.
*/
public abstract void openChatRoom(ChatRoomWrapper room);
/**
* Returns default nickname for chat room based on the given provider.
* @param pps the given protocol provider service
@ -361,14 +361,21 @@ public abstract ChatRoomWrapper findChatRoomWrapperFromChatRoom(
*/
public abstract String getDefaultNickname(
ProtocolProviderService pps);
/**
* Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
* Returns instance of the <tt>ServerChatRoomContactSourceService</tt>
* contact source.
* @return instance of the <tt>ServerChatRoomContactSourceService</tt>
* @return instance of the <tt>ServerChatRoomContactSourceService</tt>
* contact source.
*/
public abstract ContactSourceService
public abstract ContactSourceService
getServerChatRoomsContactSourceForProvider(ChatRoomProviderWrapper pps);
/**
* Returns <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
*
* @param contact the contact
* @return <tt>true</tt> if the contact is <tt>ChatRoomSourceContact</tt>
*/
public abstract boolean isMUCSourceContact(SourceContact contact);
}

@ -0,0 +1,62 @@
/*
* 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.service.protocol;
import java.util.*;
import net.java.sip.communicator.service.protocol.event.*;
/**
* This operation set provides interface for user search service.
*
* @author Hristo Terezov
*/
public interface OperationSetUserSearch
extends OperationSet
{
/**
* Creates the search manager.
*/
public void createSearchManager();
/**
* Removes search manager.
*/
public void removeSearchManager();
/**
* Performs user search for the searched string and returns the contact
* addresses of the found contacts.
*
* @param searchedString the text we want to query the server.
* @return the list of found contact addresses.
*/
public List<String> search(String searchedString);
/**
* Returns <tt>true</tt> if the user search service is enabled.
*
* @return <tt>true</tt> if the user search service is enabled.
*/
public boolean isEnabled();
/**
* Adds <tt>UserSearchProviderListener</tt> instance to the list of
* listeners.
*
* @param l the listener to be added
*/
public void addUserSearchProviderListener(UserSearchProviderListener l);
/**
* Removes <tt>UserSearchProviderListener</tt> instance from the list of
* listeners.
*
* @param l the listener to be removed
*/
public void removeUserSearchProviderListener(UserSearchProviderListener l);
}

@ -0,0 +1,69 @@
/*
* 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.service.protocol.event;
import java.util.EventObject;
import net.java.sip.communicator.service.protocol.*;
/**
* Notifies <tt>UserSearchProviderListener</tt> that a provider that supports
* user search is added or removed.
* @author Hristo Terezov
*/
public class UserSearchProviderEvent
extends EventObject
{
/**
* The serial ID.
*/
private static final long serialVersionUID = -1285649707213476360L;
/**
* A type that indicates that the provider is added.
*/
public static int PROVIDER_ADDED = 0;
/**
* A type that indicates that the provider is removed.
*/
public static int PROVIDER_REMOVED = 1;
/**
* The type of the event.
*/
private final int type;
/**
* Constructs new <tt>UserSearchProviderEvent</tt> event.
* @param provider the provider.
* @param type the type of the event.
*/
public UserSearchProviderEvent(ProtocolProviderService provider, int type)
{
super(provider);
this.type = type;
}
/**
* Returns the provider associated with the event.
* @return the provider associated with the event.
*/
public ProtocolProviderService getProvider()
{
return (ProtocolProviderService) getSource();
}
/**
* Returns the type of the event.
* @return the type of the event.
*/
public int getType()
{
return type;
}
}

@ -0,0 +1,20 @@
/*
* 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.service.protocol.event;
/**
* An interface for listener that will be notified when provider that supports
* user search is added or removed.
* @author Hristo Terezov
*/
public interface UserSearchProviderListener
{
/**
* Notifies the listener with <tt>UserSearchProviderEvent</tt> event.
* @param event the event
*/
public void onUserSearchProviderEvent(UserSearchProviderEvent event);
}
Loading…
Cancel
Save