Commit 0774f037 authored by Ryan Graham's avatar Ryan Graham Committed by ryang

These are the same changes made to search plugin in the wildfire branch

* Changed discovery category/type from "search/text" to "directory/user".
* Fixed UnsupportedOperationException if the client did not send a iq set/get prior to conducting a search.
* Fixed a possible issue that might prevent the plugin from being destroyed completely.

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@7871 b35dd754-fafc-0310-a699-88a17e54d16e
parent 36521cff
...@@ -49,10 +49,17 @@ Search Plugin Changelog ...@@ -49,10 +49,17 @@ Search Plugin Changelog
<li>Now requires Openfire 3.3.0.</li> <li>Now requires Openfire 3.3.0.</li>
</ul> </ul>
<p><b>1.3.2</b> -- April 3, 2007</p>
<ul>
<li>Changed discovery category/type from "search/text" to "directory/user".</li>
<li>Fixed UnsupportedOperationException if the client did not send a iq set/get prior to conducting a search.</li>
<li>Fixed a possible issue that might prevent the plugin from being destroyed completely.</li>
</ul>
<p><b>1.3.1</b> -- March 12, 2007</p> <p><b>1.3.1</b> -- March 12, 2007</p>
<ul> <ul>
<li>Fixed UnsupportedOperationException from occuring when using LDAP.</li> <li>Fixed UnsupportedOperationException from occuring when using LDAP.</li>
<li>On the Advanced User Search unescape username in the search results.</a> <li>On the Advanced User Search unescape username in the search results.</li>
</ul> </ul>
<p><b>1.3.0</b> -- February 28, 2007</p> <p><b>1.3.0</b> -- February 28, 2007</p>
......
/** /**
* Copyright (C) 2005 Jive Software. All rights reserved. * Copyright (C) 2005 Jive Software. All rights reserved.
* *
* This software is published under the terms of the GNU Public License (GPL), * This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution. * a copy of which is included in this distribution.
*/ */
package org.jivesoftware.openfire.plugin; package org.jivesoftware.openfire.plugin;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.QName; import org.dom4j.QName;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.PropertyEventDispatcher; import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener; import org.jivesoftware.util.PropertyEventListener;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.container.Plugin; import org.jivesoftware.openfire.container.Plugin;
import org.jivesoftware.openfire.container.PluginManager; import org.jivesoftware.openfire.container.PluginManager;
import org.jivesoftware.openfire.forms.DataForm; import org.jivesoftware.openfire.forms.DataForm;
import org.jivesoftware.openfire.forms.FormField; import org.jivesoftware.openfire.forms.FormField;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl; import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.openfire.forms.spi.XFormFieldImpl; import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.user.User; import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
import org.xmpp.component.Component; import org.xmpp.component.Component;
import org.xmpp.component.ComponentException; import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager; import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory; import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.packet.IQ; import org.xmpp.packet.IQ;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError; import org.xmpp.packet.PacketError;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
/** /**
* Provides support for Jabber Search * Provides support for Jabber Search
* (<a href="http://www.xmpp.org/extensions/xep-0055.html">XEP-0055</a>).<p> * (<a href="http://www.xmpp.org/extensions/xep-0055.html">XEP-0055</a>).<p>
* *
* The basic functionality is to query an information repository * The basic functionality is to query an information repository
* regarding the possible search fields, to send a search query, * regarding the possible search fields, to send a search query,
* and to receive search results. This implementation was primarily designed to use * and to receive search results. This implementation was primarily designed to use
* <a href="http://www.xmpp.org/extensions/xep-0004.html">Data Forms</a>, but * <a href="http://www.xmpp.org/extensions/xep-0004.html">Data Forms</a>, but
* also supports non-dataform searches. * also supports non-dataform searches.
* <p/> * <p/>
* *
* @author <a href="mailto:ryan@version2software.com">Ryan Graham</a> * @author <a href="mailto:ryan@version2software.com">Ryan Graham</a>
*/ */
public class SearchPlugin implements Component, Plugin, PropertyEventListener { public class SearchPlugin implements Component, Plugin, PropertyEventListener {
public static final String SERVICENAME = "plugin.search.serviceName"; public static final String SERVICENAME = "plugin.search.serviceName";
public static final String SERVICEENABLED = "plugin.search.serviceEnabled"; public static final String SERVICEENABLED = "plugin.search.serviceEnabled";
public static final String EXCLUDEDFIELDS = "plugin.search.excludedFields"; public static final String EXCLUDEDFIELDS = "plugin.search.excludedFields";
private UserManager userManager; private UserManager userManager;
private ComponentManager componentManager; private ComponentManager componentManager;
private PluginManager pluginManager; private PluginManager pluginManager;
private String serviceName; private String serviceName;
private boolean serviceEnabled; private boolean serviceEnabled;
private Collection<String> exculudedFields; private Collection<String> exculudedFields;
private static String serverName; private static String serverName;
private TreeMap<String, String> fieldLookup = new TreeMap<String, String>(new CaseInsensitiveComparator()); private TreeMap<String, String> fieldLookup = new TreeMap<String, String>(new CaseInsensitiveComparator());
private Map<String, String> reverseFieldLookup = new HashMap<String, String>(); private Map<String, String> reverseFieldLookup = new HashMap<String, String>();
public SearchPlugin() { public SearchPlugin() {
serviceName = JiveGlobals.getProperty(SERVICENAME, "search"); serviceName = JiveGlobals.getProperty(SERVICENAME, "search");
serviceEnabled = JiveGlobals.getBooleanProperty(SERVICEENABLED, true); serviceEnabled = JiveGlobals.getBooleanProperty(SERVICEENABLED, true);
exculudedFields = StringUtils.stringToCollection(JiveGlobals.getProperty(EXCLUDEDFIELDS, "")); exculudedFields = StringUtils.stringToCollection(JiveGlobals.getProperty(EXCLUDEDFIELDS, ""));
serverName = XMPPServer.getInstance().getServerInfo().getName(); serverName = XMPPServer.getInstance().getServerInfo().getName();
userManager = UserManager.getInstance();
// Some clients, such as Miranda, are hard-coded to search specific fields,
// so we map those fields to the fields that Openfire actually supports. // Some clients, such as Miranda, are hard-coded to search specific fields,
fieldLookup.put("jid", "Username"); // so we map those fields to the fields that Openfire actually supports.
fieldLookup.put("username", "Username"); fieldLookup.put("jid", "Username");
fieldLookup.put("first", "Name"); fieldLookup.put("username", "Username");
fieldLookup.put("last", "Name"); fieldLookup.put("first", "Name");
fieldLookup.put("nick", "Name"); fieldLookup.put("last", "Name");
fieldLookup.put("name", "Name"); fieldLookup.put("nick", "Name");
fieldLookup.put("email", "Email"); fieldLookup.put("name", "Name");
} fieldLookup.put("email", "Email");
}
public String getName() {
return pluginManager.getName(this); public String getName() {
} return pluginManager.getName(this);
}
public String getDescription() {
return pluginManager.getDescription(this); public String getDescription() {
} return pluginManager.getDescription(this);
}
public void initializePlugin(PluginManager manager, File pluginDirectory) {
pluginManager = manager; public void initializePlugin(PluginManager manager, File pluginDirectory) {
pluginManager = manager;
componentManager = ComponentManagerFactory.getComponentManager();
try { componentManager = ComponentManagerFactory.getComponentManager();
componentManager.addComponent(serviceName, this); try {
} componentManager.addComponent(serviceName, this);
catch (ComponentException e) { }
componentManager.getLog().error(e); catch (ComponentException e) {
} componentManager.getLog().error(e);
PropertyEventDispatcher.addListener(this); }
} PropertyEventDispatcher.addListener(this);
}
public void initialize(JID jid, ComponentManager componentManager) {
} public void initialize(JID jid, ComponentManager componentManager) {
}
public void start() {
} public void start() {
}
public void destroyPlugin() {
PropertyEventDispatcher.removeListener(this); public void destroyPlugin() {
pluginManager = null; PropertyEventDispatcher.removeListener(this);
try { pluginManager = null;
componentManager.removeComponent(serviceName); try {
componentManager = null; componentManager.removeComponent(serviceName);
} componentManager = null;
catch (Exception e) { }
componentManager.getLog().error(e); catch (Exception e) {
} componentManager.getLog().error(e);
userManager = null; }
fieldLookup = null; serviceName = null;
reverseFieldLookup = null; userManager = null;
exculudedFields = null; exculudedFields = null;
} serverName = null;
fieldLookup = null;
public void shutdown() { reverseFieldLookup = null;
} }
public void processPacket(Packet p) { public void shutdown() {
if (p instanceof IQ) { }
IQ packet = (IQ) p;
public void processPacket(Packet p) {
Element childElement = (packet).getChildElement(); if (p instanceof IQ) {
String namespace = null; IQ packet = (IQ) p;
if (childElement != null) {
namespace = childElement.getNamespaceURI(); Element childElement = (packet).getChildElement();
} String namespace = null;
if (childElement != null) {
if ("jabber:iq:search".equals(namespace)) { namespace = childElement.getNamespaceURI();
try { }
IQ replyPacket = handleIQ(packet);
if (replyPacket != null) { if ("jabber:iq:search".equals(namespace)) {
componentManager.sendPacket(this, replyPacket); try {
} IQ replyPacket = handleIQ(packet);
} if (replyPacket != null) {
catch (ComponentException e) { componentManager.sendPacket(this, replyPacket);
componentManager.getLog().error(e); }
} }
} catch (ComponentException e) {
else if ("http://jabber.org/protocol/disco#info".equals(namespace)) { componentManager.getLog().error(e);
try { }
IQ replyPacket = IQ.createResultIQ(packet); }
else if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
Element responseElement = replyPacket try {
.setChildElement("query", "http://jabber.org/protocol/disco#info"); IQ replyPacket = IQ.createResultIQ(packet);
responseElement.addElement("identity").addAttribute("category", "search")
.addAttribute("type", "text") Element responseElement = replyPacket
.addAttribute("name", "User Search"); .setChildElement("query", "http://jabber.org/protocol/disco#info");
responseElement.addElement("feature").addAttribute("var", "jabber:iq:search"); responseElement.addElement("identity").addAttribute("category", "directory")
.addAttribute("type", "user")
componentManager.sendPacket(this, replyPacket); .addAttribute("name", "User Search");
} responseElement.addElement("feature").addAttribute("var", "jabber:iq:search");
catch (ComponentException e) {
componentManager.getLog().error(e); componentManager.sendPacket(this, replyPacket);
} }
} catch (ComponentException e) {
else if ("http://jabber.org/protocol/disco#items".equals(namespace)) { componentManager.getLog().error(e);
try { }
IQ replyPacket = IQ.createResultIQ(packet); }
replyPacket.setChildElement("query", "http://jabber.org/protocol/disco#items"); else if ("http://jabber.org/protocol/disco#items".equals(namespace)) {
componentManager.sendPacket(this, replyPacket); try {
} IQ replyPacket = IQ.createResultIQ(packet);
catch (ComponentException e) { replyPacket.setChildElement("query", "http://jabber.org/protocol/disco#items");
componentManager.getLog().error(e); componentManager.sendPacket(this, replyPacket);
} }
} catch (ComponentException e) {
} componentManager.getLog().error(e);
} }
}
private IQ handleIQ(IQ packet) { }
if (!serviceEnabled) { }
return replyDisabled(packet);
} private IQ handleIQ(IQ packet) {
if (!serviceEnabled) {
if (IQ.Type.get.equals(packet.getType())) { return replyDisabled(packet);
return processGetPacket(packet); }
}
else if (IQ.Type.set.equals(packet.getType())) { if (IQ.Type.get.equals(packet.getType())) {
return processSetPacket(packet); return processGetPacket(packet);
} }
else if (IQ.Type.result.equals(packet.getType()) || IQ.Type.error.equals(packet.getType())) { else if (IQ.Type.set.equals(packet.getType())) {
// Ignore return processSetPacket(packet);
} }
else { else if (IQ.Type.result.equals(packet.getType()) || IQ.Type.error.equals(packet.getType())) {
// Unknown type was sent so return an error // Ignore
IQ reply = new IQ(IQ.Type.error, packet.getID()); }
reply.setFrom(packet.getTo()); else {
reply.setTo(packet.getFrom()); // Unknown type was sent so return an error
reply.setError(PacketError.Condition.bad_request); IQ reply = new IQ(IQ.Type.error, packet.getID());
return reply; reply.setFrom(packet.getTo());
} reply.setTo(packet.getFrom());
reply.setError(PacketError.Condition.bad_request);
return null; return reply;
} }
private IQ replyDisabled(IQ packet) { return null;
IQ replyPacket = IQ.createResultIQ(packet); }
Element reply = replyPacket.setChildElement("query", "jabber:iq:search");
XDataFormImpl unavailableForm = new XDataFormImpl(DataForm.TYPE_CANCEL); private IQ replyDisabled(IQ packet) {
unavailableForm.setTitle(LocaleUtils.getLocalizedString("advance.user.search.title", "search")); IQ replyPacket = IQ.createResultIQ(packet);
unavailableForm.addInstruction(LocaleUtils.getLocalizedString("search.service_unavailable", "search")); Element reply = replyPacket.setChildElement("query", "jabber:iq:search");
reply.add(unavailableForm.asXMLElement()); XDataFormImpl unavailableForm = new XDataFormImpl(DataForm.TYPE_CANCEL);
unavailableForm.setTitle(LocaleUtils.getLocalizedString("advance.user.search.title", "search"));
return replyPacket; unavailableForm.addInstruction(LocaleUtils.getLocalizedString("search.service_unavailable", "search"));
} reply.add(unavailableForm.asXMLElement());
private IQ processGetPacket(IQ packet) { return replyPacket;
IQ replyPacket = IQ.createResultIQ(packet); }
Element queryResult = DocumentHelper.createElement(QName.get("query", "jabber:iq:search")); private IQ processGetPacket(IQ packet) {
IQ replyPacket = IQ.createResultIQ(packet);
String instructions = LocaleUtils.getLocalizedString("advance.user.search.details", "search");
Element queryResult = DocumentHelper.createElement(QName.get("query", "jabber:iq:search"));
// non-data form
queryResult.addElement("instructions").addText(instructions); String instructions = LocaleUtils.getLocalizedString("advance.user.search.details", "search");
XDataFormImpl searchForm = new XDataFormImpl(DataForm.TYPE_FORM); // non-data form
searchForm.setTitle(LocaleUtils.getLocalizedString("advance.user.search.title", "search")); queryResult.addElement("instructions").addText(instructions);
searchForm.addInstruction(instructions);
XDataFormImpl searchForm = new XDataFormImpl(DataForm.TYPE_FORM);
XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE"); searchForm.setTitle(LocaleUtils.getLocalizedString("advance.user.search.title", "search"));
field.setType(FormField.TYPE_HIDDEN); searchForm.addInstruction(instructions);
field.addValue("jabber:iq:search");
searchForm.addField(field); XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
field.setType(FormField.TYPE_HIDDEN);
field = new XFormFieldImpl("search"); field.addValue("jabber:iq:search");
field.setType(FormField.TYPE_TEXT_SINGLE); searchForm.addField(field);
field.setLabel(LocaleUtils.getLocalizedString("advance.user.search.search", "search"));
field.setRequired(true); field = new XFormFieldImpl("search");
searchForm.addField(field); field.setType(FormField.TYPE_TEXT_SINGLE);
field.setLabel(LocaleUtils.getLocalizedString("advance.user.search.search", "search"));
for (String searchField : getFilteredSearchFields()) { field.setRequired(true);
// non-data form searchForm.addField(field);
queryResult.addElement(searchField);
for (String searchField : getFilteredSearchFields()) {
field = new XFormFieldImpl(searchField); // non-data form
field.setType(FormField.TYPE_BOOLEAN); queryResult.addElement(searchField);
field.addValue("1");
field.setLabel(searchField); field = new XFormFieldImpl(searchField);
field.setRequired(false); field.setType(FormField.TYPE_BOOLEAN);
searchForm.addField(field); field.addValue("1");
} field.setLabel(searchField);
field.setRequired(false);
queryResult.add(searchForm.asXMLElement()); searchForm.addField(field);
replyPacket.setChildElement(queryResult); }
return replyPacket; queryResult.add(searchForm.asXMLElement());
} replyPacket.setChildElement(queryResult);
private IQ processSetPacket(IQ packet) { return replyPacket;
Set<User> users = new HashSet<User>(); }
Element incomingForm = packet.getChildElement(); private IQ processSetPacket(IQ packet) {
boolean isDataFormQuery = (incomingForm.element(QName.get("x", "jabber:x:data")) != null); Set<User> users = new HashSet<User>();
Hashtable<String, String> searchList = extractSearchQuery(incomingForm); Element incomingForm = packet.getChildElement();
Enumeration<String> searchIter = searchList.keys(); boolean isDataFormQuery = (incomingForm.element(QName.get("x", "jabber:x:data")) != null);
while (searchIter.hasMoreElements()) {
String field = searchIter.nextElement(); Hashtable<String, String> searchList = extractSearchQuery(incomingForm);
String query = searchList.get(field); Enumeration<String> searchIter = searchList.keys();
while (searchIter.hasMoreElements()) {
Collection<User> foundUsers = new ArrayList<User>(); String field = searchIter.nextElement();
if (userManager != null) { String query = searchList.get(field);
if (query.length() > 0 && !query.equals("jabber:iq:search")) {
foundUsers.addAll(userManager.findUsers(new HashSet<String>( Collection<User> foundUsers = new ArrayList<User>();
Arrays.asList((field))), query)); if (userManager != null) {
} if (query.length() > 0 && !query.equals("jabber:iq:search")) {
} foundUsers.addAll(userManager.findUsers(new HashSet<String>(
else { Arrays.asList((field))), query));
foundUsers.addAll(findUsers(field, query)); }
} }
else {
//occasionally null a User is returned so filter them out foundUsers.addAll(findUsers(field, query));
for (User user : foundUsers) { }
if (user != null) {
users.add(user); //occasionally null a User is returned so filter them out
} for (User user : foundUsers) {
} if (user != null) {
} users.add(user);
}
if (isDataFormQuery) { }
return replyDataFormResult(users, packet); }
}
else { if (isDataFormQuery) {
return replyNonDataFormResult(users, packet); return replyDataFormResult(users, packet);
} }
} else {
return replyNonDataFormResult(users, packet);
private Hashtable<String, String> extractSearchQuery(Element incomingForm) { }
Hashtable<String, String> searchList = new Hashtable<String, String>(); }
Element form = incomingForm.element(QName.get("x", "jabber:x:data"));
if (form == null) { private Hashtable<String, String> extractSearchQuery(Element incomingForm) {
//since not all clients request which fields are available for searching Hashtable<String, String> searchList = new Hashtable<String, String>();
//attempt to match submitted fields with available search fields Element form = incomingForm.element(QName.get("x", "jabber:x:data"));
Iterator iter = incomingForm.elementIterator(); if (form == null) {
while (iter.hasNext()) { //since not all clients request which fields are available for searching
Element element = (Element) iter.next(); //attempt to match submitted fields with available search fields
String name = element.getName(); Iterator iter = incomingForm.elementIterator();
while (iter.hasNext()) {
if (fieldLookup.containsKey(name)) { Element element = (Element) iter.next();
//make best effort to map the fields submitted by String name = element.getName();
//the client to those that Openfire can search
reverseFieldLookup.put(fieldLookup.get(name), name); if (fieldLookup.containsKey(name)) {
searchList.put(fieldLookup.get(name), element.getText()); //make best effort to map the fields submitted by
} //the client to those that Openfire can search
} reverseFieldLookup.put(fieldLookup.get(name), name);
} searchList.put(fieldLookup.get(name), element.getText());
else { }
List<String> searchFields = new ArrayList<String>(); }
String search = ""; }
else {
Iterator fields = form.elementIterator("field"); List<String> searchFields = new ArrayList<String>();
while (fields.hasNext()) { String search = "";
Element searchField = (Element) fields.next();
Iterator fields = form.elementIterator("field");
String field = searchField.attributeValue("var"); while (fields.hasNext()) {
String value = ""; Element searchField = (Element) fields.next();
if (searchField.element("value") != null) {
value = searchField.element("value").getTextTrim(); String field = searchField.attributeValue("var");
} String value = "";
if (field.equals("search")) { if (searchField.element("value") != null) {
search = value; value = searchField.element("value").getTextTrim();
} }
else if (value.equals("1")) { if (field.equals("search")) {
searchFields.add(field); search = value;
} }
} else if (value.equals("1")) {
searchFields.add(field);
for (String field : searchFields) { }
searchList.put(field, search); }
}
} for (String field : searchFields) {
searchList.put(field, search);
return searchList; }
} }
private IQ replyDataFormResult(Set<User> users, IQ packet) { return searchList;
XDataFormImpl searchResults = new XDataFormImpl(DataForm.TYPE_RESULT); }
XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE"); private IQ replyDataFormResult(Set<User> users, IQ packet) {
field.setType(FormField.TYPE_HIDDEN); XDataFormImpl searchResults = new XDataFormImpl(DataForm.TYPE_RESULT);
searchResults.addField(field);
XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
field = new XFormFieldImpl("jid"); field.setType(FormField.TYPE_HIDDEN);
field.setLabel("JID"); searchResults.addField(field);
searchResults.addReportedField(field);
field = new XFormFieldImpl("jid");
for (String fieldName : getFilteredSearchFields()) { field.setLabel("JID");
field = new XFormFieldImpl(fieldName); searchResults.addReportedField(field);
field.setLabel(fieldName);
searchResults.addReportedField(field); for (String fieldName : getFilteredSearchFields()) {
} field = new XFormFieldImpl(fieldName);
field.setLabel(fieldName);
for (User user : users) { searchResults.addReportedField(field);
String username = user.getUsername(); }
ArrayList<XFormFieldImpl> items = new ArrayList<XFormFieldImpl>(); for (User user : users) {
String username = user.getUsername();
XFormFieldImpl fieldJID = new XFormFieldImpl("jid");
fieldJID.addValue(username + "@" + serverName); ArrayList<XFormFieldImpl> items = new ArrayList<XFormFieldImpl>();
items.add(fieldJID);
XFormFieldImpl fieldJID = new XFormFieldImpl("jid");
XFormFieldImpl fieldUsername = new XFormFieldImpl("Username"); fieldJID.addValue(username + "@" + serverName);
fieldUsername.addValue(username); items.add(fieldJID);
items.add(fieldUsername);
XFormFieldImpl fieldUsername = new XFormFieldImpl("Username");
XFormFieldImpl fieldName = new XFormFieldImpl("Name"); fieldUsername.addValue(username);
fieldName.addValue(removeNull(user.getName())); items.add(fieldUsername);
items.add(fieldName);
XFormFieldImpl fieldName = new XFormFieldImpl("Name");
XFormFieldImpl fieldEmail = new XFormFieldImpl("Email"); fieldName.addValue(removeNull(user.getName()));
fieldEmail.addValue(removeNull(user.getEmail())); items.add(fieldName);
items.add(fieldEmail);
XFormFieldImpl fieldEmail = new XFormFieldImpl("Email");
searchResults.addItemFields(items); fieldEmail.addValue(removeNull(user.getEmail()));
} items.add(fieldEmail);
IQ replyPacket = IQ.createResultIQ(packet); searchResults.addItemFields(items);
Element reply = replyPacket.setChildElement("query", "jabber:iq:search"); }
reply.add(searchResults.asXMLElement());
IQ replyPacket = IQ.createResultIQ(packet);
return replyPacket; Element reply = replyPacket.setChildElement("query", "jabber:iq:search");
} reply.add(searchResults.asXMLElement());
private IQ replyNonDataFormResult(Set<User> users, IQ packet) { return replyPacket;
IQ replyPacket = IQ.createResultIQ(packet); }
Element replyQuery = replyPacket.setChildElement("query", "jabber:iq:search");
private IQ replyNonDataFormResult(Set<User> users, IQ packet) {
for (User user : users) { IQ replyPacket = IQ.createResultIQ(packet);
Element item = replyQuery.addElement("item"); Element replyQuery = replyPacket.setChildElement("query", "jabber:iq:search");
item.addAttribute("jid", user.getUsername() + "@" + serverName);
for (User user : users) {
//return to the client the same fields that were submitted Element item = replyQuery.addElement("item");
for (String field : reverseFieldLookup.keySet()) { item.addAttribute("jid", user.getUsername() + "@" + serverName);
if ("Username".equals(field)) {
Element element = item.addElement(reverseFieldLookup.get(field)); //return to the client the same fields that were submitted
element.addText(user.getUsername()); for (String field : reverseFieldLookup.keySet()) {
} if ("Username".equals(field)) {
Element element = item.addElement(reverseFieldLookup.get(field));
if ("Name".equals(field)) { element.addText(user.getUsername());
Element element = item.addElement(reverseFieldLookup.get(field)); }
element.addText(removeNull(user.getName()));
} if ("Name".equals(field)) {
Element element = item.addElement(reverseFieldLookup.get(field));
if ("Email".equals(field)) { element.addText(removeNull(user.getName()));
Element element = item.addElement(reverseFieldLookup.get(field)); }
element.addText(removeNull(user.getEmail()));
} if ("Email".equals(field)) {
} Element element = item.addElement(reverseFieldLookup.get(field));
} element.addText(removeNull(user.getEmail()));
}
return replyPacket; }
} }
public String getServiceName() { return replyPacket;
return serviceName; }
}
public String getServiceName() {
public void setServiceName(String name) { return serviceName;
changeServiceName(name); }
JiveGlobals.setProperty(SERVICENAME, name);
} public void setServiceName(String name) {
changeServiceName(name);
public boolean getServiceEnabled() { JiveGlobals.setProperty(SERVICENAME, name);
return serviceEnabled; }
}
public boolean getServiceEnabled() {
public void setServiceEnabled(boolean enabled) { return serviceEnabled;
serviceEnabled = enabled; }
JiveGlobals.setProperty(SERVICEENABLED, enabled ? "true" : "false");
} public void setServiceEnabled(boolean enabled) {
serviceEnabled = enabled;
/** JiveGlobals.setProperty(SERVICEENABLED, enabled ? "true" : "false");
* Returns the collection of searchable field names that does not include the fields }
* listed in the EXCLUDEDFIELDS property list.
*/ /**
public Collection<String> getFilteredSearchFields() { * Returns the collection of searchable field names that does not include the fields
Collection<String> searchFields; * listed in the EXCLUDEDFIELDS property list.
*/
// See if the installed provider supports searching. If not, workaround public Collection<String> getFilteredSearchFields() {
// by providing our own searching. Collection<String> searchFields;
try {
userManager = UserManager.getInstance(); // See if the installed provider supports searching. If not, workaround
searchFields = new ArrayList<String>(userManager.getSearchFields()); // by providing our own searching.
} try {
catch (UnsupportedOperationException uoe) { searchFields = new ArrayList<String>(userManager.getSearchFields());
// Use a SearchPluginUserManager instead. }
searchFields = getSearchPluginUserManagerSearchFields(); catch (UnsupportedOperationException uoe) {
} // Use a SearchPluginUserManager instead.
searchFields = getSearchPluginUserManagerSearchFields();
searchFields.removeAll(exculudedFields); }
return searchFields; searchFields.removeAll(exculudedFields);
}
return searchFields;
public void setExcludedFields(Collection<String> exculudedFields) { }
this.exculudedFields = exculudedFields;
JiveGlobals.setProperty(EXCLUDEDFIELDS, StringUtils.collectionToString(exculudedFields)); public void setExcludedFields(Collection<String> exculudedFields) {
} this.exculudedFields = exculudedFields;
JiveGlobals.setProperty(EXCLUDEDFIELDS, StringUtils.collectionToString(exculudedFields));
public void propertySet(String property, Map params) { }
if (property.equals(SERVICEENABLED)) {
this.serviceEnabled = Boolean.parseBoolean((String)params.get("value")); public void propertySet(String property, Map params) {
} if (property.equals(SERVICEENABLED)) {
else if (property.equals(SERVICENAME)) { this.serviceEnabled = Boolean.parseBoolean((String)params.get("value"));
changeServiceName((String)params.get("value")); }
} else if (property.equals(SERVICENAME)) {
else if (property.equals(EXCLUDEDFIELDS)) { changeServiceName((String)params.get("value"));
exculudedFields = StringUtils.stringToCollection(JiveGlobals.getProperty(EXCLUDEDFIELDS, (String)params.get("value"))); }
} else if (property.equals(EXCLUDEDFIELDS)) {
} exculudedFields = StringUtils.stringToCollection(JiveGlobals.getProperty(EXCLUDEDFIELDS, (String)params.get("value")));
}
public void propertyDeleted(String property, Map params) { }
if (property.equals(SERVICEENABLED)) {
this.serviceEnabled = true; public void propertyDeleted(String property, Map params) {
} if (property.equals(SERVICEENABLED)) {
else if (property.equals(SERVICENAME)) { this.serviceEnabled = true;
changeServiceName("search"); }
} else if (property.equals(SERVICENAME)) {
else if (property.equals(EXCLUDEDFIELDS)) { changeServiceName("search");
exculudedFields = new ArrayList<String>(); }
} else if (property.equals(EXCLUDEDFIELDS)) {
} exculudedFields = new ArrayList<String>();
}
public void xmlPropertySet(String property, Map params) { }
// not used
} public void xmlPropertySet(String property, Map params) {
// not used
public void xmlPropertyDeleted(String property, Map params) { }
// not used
} public void xmlPropertyDeleted(String property, Map params) {
// not used
private void changeServiceName(String serviceName) { }
if (serviceName == null) {
throw new NullPointerException("Service name cannot be null"); private void changeServiceName(String serviceName) {
} if (serviceName == null) {
throw new NullPointerException("Service name cannot be null");
if (this.serviceName.equals(serviceName)) { }
return;
} if (this.serviceName.equals(serviceName)) {
return;
// Re-register the service. }
try {
componentManager.removeComponent(this.serviceName); // Re-register the service.
} try {
catch (Exception e) { componentManager.removeComponent(this.serviceName);
componentManager.getLog().error(e); }
} catch (Exception e) {
componentManager.getLog().error(e);
try { }
componentManager.addComponent(serviceName, this);
} try {
catch (Exception e) { componentManager.addComponent(serviceName, this);
componentManager.getLog().error(e); }
} catch (Exception e) {
componentManager.getLog().error(e);
this.serviceName = serviceName; }
}
this.serviceName = serviceName;
private class CaseInsensitiveComparator implements Comparator<String> { }
public int compare(String s1, String s2) {
return s1.compareToIgnoreCase(s2); private class CaseInsensitiveComparator implements Comparator<String> {
} public int compare(String s1, String s2) {
} return s1.compareToIgnoreCase(s2);
}
private String removeNull(String s) { }
if (s == null) {
return ""; private String removeNull(String s) {
} if (s == null) {
return "";
return s.trim(); }
}
return s.trim();
/** }
* Returns the collection of field names that can be used to search for a
* user. Typical fields are username, name, and email. These values can be /**
* used to contruct a data form. * Returns the collection of field names that can be used to search for a
*/ * user. Typical fields are username, name, and email. These values can be
public Collection<String> getSearchPluginUserManagerSearchFields() { * used to contruct a data form.
return Arrays.asList("Username", "Name", "Email"); */
} public Collection<String> getSearchPluginUserManagerSearchFields() {
return Arrays.asList("Username", "Name", "Email");
/** }
* Finds a user using the specified field and query string. For example, a
* field name of "email" and query of "jsmith@example.com" would search for /**
* the user with that email address. Wildcard (*) characters are allowed as * Finds a user using the specified field and query string. For example, a
* part of queries. * field name of "email" and query of "jsmith@example.com" would search for
* * the user with that email address. Wildcard (*) characters are allowed as
* A possible future improvement would be to have a third parameter that * part of queries.
* sets the maximum number of users returned and/or the number of users *
* that are searched. * A possible future improvement would be to have a third parameter that
*/ * sets the maximum number of users returned and/or the number of users
public Collection<User> findUsers(String field, String query) { * that are searched.
List<User> foundUsers = new ArrayList<User>(); */
public Collection<User> findUsers(String field, String query) {
if (!getSearchPluginUserManagerSearchFields().contains(field)) { List<User> foundUsers = new ArrayList<User>();
return foundUsers;
} if (!getSearchPluginUserManagerSearchFields().contains(field)) {
return foundUsers;
int index = query.indexOf("*"); }
if (index == -1) {
Collection<User> users = userManager.getUsers(); int index = query.indexOf("*");
for (User user : users) { if (index == -1) {
if (field.equals("Username")) { Collection<User> users = userManager.getUsers();
try { for (User user : users) {
foundUsers.add(userManager.getUser(query)); if (field.equals("Username")) {
return foundUsers; try {
} foundUsers.add(userManager.getUser(query));
catch (UserNotFoundException e) { return foundUsers;
Log.error("Error getting user", e); }
} catch (UserNotFoundException e) {
} Log.error("Error getting user", e);
else if (field.equals("Name")) { }
if (query.equalsIgnoreCase(user.getName())) { }
foundUsers.add(user); else if (field.equals("Name")) {
} if (query.equalsIgnoreCase(user.getName())) {
} foundUsers.add(user);
else if (field.equals("Email")) { }
if (user.getEmail() != null) { }
if (query.equalsIgnoreCase(user.getEmail())) { else if (field.equals("Email")) {
foundUsers.add(user); if (user.getEmail() != null) {
} if (query.equalsIgnoreCase(user.getEmail())) {
} foundUsers.add(user);
} }
} }
} }
else { }
String prefix = query.substring(0, index); }
Collection<User> users = userManager.getUsers(); else {
for (User user : users) { String prefix = query.substring(0, index);
String userInfo = ""; Collection<User> users = userManager.getUsers();
if (field.equals("Username")) { for (User user : users) {
userInfo = user.getUsername(); String userInfo = "";
} if (field.equals("Username")) {
else if (field.equals("Name")) { userInfo = user.getUsername();
userInfo = user.getName(); }
} else if (field.equals("Name")) {
else if (field.equals("Email")) { userInfo = user.getName();
userInfo = user.getEmail() == null ? "" : user.getEmail(); }
} else if (field.equals("Email")) {
userInfo = user.getEmail() == null ? "" : user.getEmail();
if (index < userInfo.length()) { }
if (userInfo.substring(0, index).equalsIgnoreCase(prefix)) {
foundUsers.add(user); if (index < userInfo.length()) {
} if (userInfo.substring(0, index).equalsIgnoreCase(prefix)) {
} foundUsers.add(user);
} }
} }
}
return foundUsers; }
}
} return foundUsers;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment