Commit 823bb9c9 authored by Ryan Graham's avatar Ryan Graham Committed by ryang

updated to support admin console searches and configuration


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1359 b35dd754-fafc-0310-a699-88a17e54d16e
parent 6233ff36
...@@ -44,6 +44,14 @@ ...@@ -44,6 +44,14 @@
Search Plugin Changelog Search Plugin Changelog
</h1> </h1>
<p><b>1.1</b> -- May 17, 2005</b></p>
<ul>
<li>Added a page to the Admin Console to allow the enabling/disabling of the search service and to change the service name.
<li>Added a page to the Admin Console to allow searching similiar to what is done on the client side.
<li>Added a hidden FORM_TYPE field per the JEP-0055 spec.
<li>Some intenternal code refactoring.
</ul>
<p><b>1.0.6</b> -- April 12, 2005</b></p> <p><b>1.0.6</b> -- April 12, 2005</b></p>
<ul> <ul>
<li>Changed the ui to use a single text field with multiple checkboxes to specify which fields are to be searched (thanks jfroehlich).</li> <li>Changed the ui to use a single text field with multiple checkboxes to specify which fields are to be searched (thanks jfroehlich).</li>
......
...@@ -5,6 +5,23 @@ ...@@ -5,6 +5,23 @@
<name>Search Plugin</name> <name>Search Plugin</name>
<description>Provides support for Jabber Search (JEP-0055)</description> <description>Provides support for Jabber Search (JEP-0055)</description>
<author>Ryan Graham</author> <author>Ryan Graham</author>
<version>1.0.6</version> <version>1.1</version>
<minServerVersion>2.1.2</minServerVersion> <minServerVersion>2.1.3</minServerVersion>
<adminconsole>
<tab id="tab-server">
<sidebar id="sidebar-server-settings">
<item id="search-props-edit-form" name="Search Search Properties"
url="search-props-edit-form.jsp"
description="Edit search service properties" />
</sidebar>
</tab>
<tab id="tab-users">
<sidebar id="sidebar-users">
<item id="advance-user-search" name="Advance User Search"
url="advance-user-search.jsp"
description="Advanced user search" />
</sidebar>
</tab>
</adminconsole>
</plugin> </plugin>
\ No newline at end of file
...@@ -62,7 +62,11 @@ copy the new search.jar into the plugins directory of your Jive Messenger instal ...@@ -62,7 +62,11 @@ copy the new search.jar into the plugins directory of your Jive Messenger instal
<h2>Configuration</h2> <h2>Configuration</h2>
Presently, there is nothing that can be configured for the search plugin. The search plugin is configured via the "Search Service Properites" sidebar item located under the "Server" tab
in the Jive Messenger Admin Console. By default, after the search plugin has been deployed all of its features
are enabled. To enable or disable the plugin select the appropirate radio button and then click on the
"Save Properties" button. To change the service name enter the new name for the service and then click on the
"Save Properties" button
<h2>Using the Plugin</h2> <h2>Using the Plugin</h2>
...@@ -76,25 +80,31 @@ sure the name checkbox is selected. The "*" symbol acts as a wildcard so your se ...@@ -76,25 +80,31 @@ sure the name checkbox is selected. The "*" symbol acts as a wildcard so your se
only "John Smith" but all the users whose name begins with "John S", i.e. "John Slater", "John Salazar", etc. only "John Smith" but all the users whose name begins with "John S", i.e. "John Slater", "John Salazar", etc.
</p> </p>
<li>
Admin Console - Navigate to the "Advance User Search" sidebar item located in under the "Users/Groups" tab.
</li>
<br>
<li> <li>
Exodus - After clicking on the magnifying glass with the red "+" sign, a screen will appear displaying the search Exodus - After clicking on the magnifying glass with the red "+" sign, a screen will appear displaying the search
service that will be used which will be used. Click on the "Next" button and the search screen will service that will be used which will be used. Click on the "Next" button and the search screen will
be visible. be visible.
</li> </li>
<br> <br>
<li> <li>
JAJC - After clicking on the "Jabber Browser" icon (the third icon from the left), a Jabber browser screen will appear and on the right-hand side, there will be a list of services. Double-click on the "User Search" JAJC - After clicking on the "Jabber Browser" icon (the third icon from the left), a Jabber browser screen will appear and on the right-hand side, there will be a list of services. Double-click on the "User Search"
entry and a new screen will appear. Finally, on the left-hand side of the screen, click on the "Search" item to view the search screen. entry and a new screen will appear. Finally, on the left-hand side of the screen, click on the "Search" item to view the search screen.
</li> </li>
<br> <br>
<!--
<li> <li>
Pandion - From the "Actions" menu click on "Add a contact...", on the screen that appears makes sure Pandion (v2.1.2) - From the "Actions" menu click on "Add a contact...", on the screen that appears makes sure
the "I want to search for someone." radio button is selected and then click on the "Next >" button to the "I want to search for someone." radio button is selected and then click on the "Next >" button to
view the search screen. view the search screen.
</li> </li>
<br> <br>
-->
<li> <li>
Psi - On the lower left-hand corner of the client, click on the main Psi toolbar, select "Service Discovery", and click on your username. After the service discovery windowappears, select the "User Search" entry and click on Psi - On the lower left-hand corner of the client, click on the main Psi toolbar, select "Service Discovery", and click on your username. After the service discovery windowappears, select the "User Search" entry and click on
the magnifying glass at the top of the window to view the search screen. the magnifying glass at the top of the window to view the search screen.
......
...@@ -16,6 +16,7 @@ import java.util.HashSet; ...@@ -16,6 +16,7 @@ import java.util.HashSet;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import org.dom4j.Attribute; import org.dom4j.Attribute;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
...@@ -31,7 +32,9 @@ import org.jivesoftware.messenger.forms.spi.XFormFieldImpl; ...@@ -31,7 +32,9 @@ import org.jivesoftware.messenger.forms.spi.XFormFieldImpl;
import org.jivesoftware.messenger.user.User; import org.jivesoftware.messenger.user.User;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.PropertyEventListener;
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;
...@@ -54,13 +57,15 @@ import org.xmpp.packet.Packet; ...@@ -54,13 +57,15 @@ import org.xmpp.packet.Packet;
* *
* @author Ryan Graham * @author Ryan Graham
*/ */
public class SearchPlugin implements Component, Plugin { public class SearchPlugin implements Component, Plugin, PropertyEventListener {
private XMPPServer server; private XMPPServer server;
private UserManager userManager; private UserManager userManager;
private ComponentManager componentManager; private ComponentManager componentManager;
private PluginManager pluginManager; private PluginManager pluginManager;
private static final String SERVICE_NAME = "search"; private String serviceName;
private boolean serviceEnabled;
private static String serverName; private static String serverName;
private static String instructions = "The following fields are available for search. " private static String instructions = "The following fields are available for search. "
...@@ -71,6 +76,9 @@ public class SearchPlugin implements Component, Plugin { ...@@ -71,6 +76,9 @@ public class SearchPlugin implements Component, Plugin {
private Collection<String> searchFields; private Collection<String> searchFields;
public SearchPlugin() { public SearchPlugin() {
serviceName = JiveGlobals.getProperty("plugin.search.serviceName", "search");
serviceEnabled = JiveGlobals.getBooleanProperty("plugin.broadcast.serviceEnabled", true);
server = XMPPServer.getInstance(); server = XMPPServer.getInstance();
serverName = server.getServerInfo().getName(); serverName = server.getServerInfo().getName();
// See if the installed provider supports searching. If not, workaround // See if the installed provider supports searching. If not, workaround
...@@ -95,20 +103,12 @@ public class SearchPlugin implements Component, Plugin { ...@@ -95,20 +103,12 @@ public class SearchPlugin implements Component, Plugin {
return pluginManager.getDescription(this); return pluginManager.getDescription(this);
} }
public String getAuthor() {
return pluginManager.getAuthor(this);
}
public String getVersion() {
return pluginManager.getVersion(this);
}
public void initializePlugin(PluginManager manager, File pluginDirectory) { public void initializePlugin(PluginManager manager, File pluginDirectory) {
pluginManager = manager; pluginManager = manager;
componentManager = ComponentManagerFactory.getComponentManager(); componentManager = ComponentManagerFactory.getComponentManager();
try { try {
componentManager.addComponent(SERVICE_NAME, this); componentManager.addComponent(serviceName, this);
} }
catch (Exception e) { catch (Exception e) {
componentManager.getLog().error(e); componentManager.getLog().error(e);
...@@ -124,16 +124,18 @@ public class SearchPlugin implements Component, Plugin { ...@@ -124,16 +124,18 @@ public class SearchPlugin implements Component, Plugin {
searchForm.setTitle("User Search"); searchForm.setTitle("User Search");
searchForm.addInstruction(instructions); searchForm.addInstruction(instructions);
XFormFieldImpl field = new XFormFieldImpl("search"); XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
field.setType(FormField.TYPE_HIDDEN);
field.addValue("jabber:iq:search");
searchForm.addField(field);
field = new XFormFieldImpl("search");
field.setType(FormField.TYPE_TEXT_SINGLE); field.setType(FormField.TYPE_TEXT_SINGLE);
field.setLabel("Search"); field.setLabel("Search");
field.setRequired(false); field.setRequired(false);
searchForm.addField(field); searchForm.addField(field);
Iterator iter = searchFields.iterator(); for (String searchField : searchFields) {
while (iter.hasNext()) {
String searchField = (String) iter.next();
//non-data form //non-data form
probeResult.addElement(searchField.toLowerCase()); probeResult.addElement(searchField.toLowerCase());
...@@ -158,7 +160,7 @@ public class SearchPlugin implements Component, Plugin { ...@@ -158,7 +160,7 @@ public class SearchPlugin implements Component, Plugin {
public void destroyPlugin() { public void destroyPlugin() {
pluginManager = null; pluginManager = null;
try { try {
componentManager.removeComponent(SERVICE_NAME); componentManager.removeComponent(serviceName);
componentManager = null; componentManager = null;
} }
catch (Exception e) { catch (Exception e) {
...@@ -226,9 +228,12 @@ public class SearchPlugin implements Component, Plugin { ...@@ -226,9 +228,12 @@ public class SearchPlugin implements Component, Plugin {
} }
private IQ handleIQ(IQ packet) { private IQ handleIQ(IQ packet) {
if (!serviceEnabled) {
return replyDisabled(packet);
}
if (IQ.Type.get.equals(packet.getType())) { if (IQ.Type.get.equals(packet.getType())) {
return processGetPacket(packet); return processGetPacket(packet);
} }
else if (IQ.Type.set.equals(packet.getType())) { else if (IQ.Type.set.equals(packet.getType())) {
return processSetPacket(packet); return processSetPacket(packet);
...@@ -237,6 +242,20 @@ public class SearchPlugin implements Component, Plugin { ...@@ -237,6 +242,20 @@ public class SearchPlugin implements Component, Plugin {
return null; return null;
} }
private IQ replyDisabled(IQ packet) {
Element reply = DocumentHelper.createElement(QName.get("query", "jabber:iq:search"));
XDataFormImpl unavailableForm = new XDataFormImpl(DataForm.TYPE_CANCEL);
unavailableForm.setTitle("User Search");
unavailableForm.addInstruction("This service is unavailable.");
reply.add(unavailableForm.asXMLElement());
IQ replyPacket = IQ.createResultIQ(packet);
replyPacket.setChildElement("query", "jabber:iq:search");
replyPacket.setChildElement(reply.createCopy());
return replyPacket;
}
private IQ processGetPacket(IQ packet) { private IQ processGetPacket(IQ packet) {
IQ replyPacket = IQ.createResultIQ(packet); IQ replyPacket = IQ.createResultIQ(packet);
replyPacket.setChildElement("query", "jabber:iq:search"); replyPacket.setChildElement("query", "jabber:iq:search");
...@@ -257,31 +276,29 @@ public class SearchPlugin implements Component, Plugin { ...@@ -257,31 +276,29 @@ public class SearchPlugin implements Component, Plugin {
String field = (String) searchIter.nextElement(); String field = (String) searchIter.nextElement();
String query = (String) searchList.get(field); String query = (String) searchList.get(field);
Iterator foundIter = null; Collection<User> foundUsers = new ArrayList<User>();
if (userManager != null) { if (userManager != null) {
if (query.length() > 0 && !query.equals("jabber:iq:search")) { if (query.length() > 0 && !query.equals("jabber:iq:search")) {
foundIter = userManager.findUsers(new HashSet<String>( foundUsers.addAll(userManager.findUsers(new HashSet<String>(
Arrays.asList((field))), query).iterator(); Arrays.asList((field))), query));
} }
} }
else { else {
foundIter = findUsers(field, query).iterator(); foundUsers.addAll(findUsers(field, query));
} }
// Filter out all duplicate users. // Filter out all duplicate users.
if (foundIter != null) { for (User user : foundUsers) {
while (foundIter.hasNext()) {
User user = (User) foundIter.next();
if (!users.contains(user)) { if (!users.contains(user)) {
users.add(user); users.add(user);
} }
} }
} }
}
if (isDataFormQuery) { if (isDataFormQuery) {
return replyDataFormResult(users, packet); return replyDataFormResult(users, packet);
} else { }
else {
return replyNonDataFormResult(users, packet); return replyNonDataFormResult(users, packet);
} }
} }
...@@ -337,9 +354,7 @@ public class SearchPlugin implements Component, Plugin { ...@@ -337,9 +354,7 @@ public class SearchPlugin implements Component, Plugin {
} }
} }
Iterator iter = searchFields.iterator(); for (String field : searchFields) {
while (iter.hasNext()) {
String field = (String) iter.next();
searchList.put(field, search); searchList.put(field, search);
} }
} }
...@@ -347,10 +362,14 @@ public class SearchPlugin implements Component, Plugin { ...@@ -347,10 +362,14 @@ public class SearchPlugin implements Component, Plugin {
return searchList; return searchList;
} }
private IQ replyDataFormResult(List users, IQ packet) { private IQ replyDataFormResult(List<User> users, IQ packet) {
XDataFormImpl searchResults = new XDataFormImpl(DataForm.TYPE_RESULT); XDataFormImpl searchResults = new XDataFormImpl(DataForm.TYPE_RESULT);
XFormFieldImpl field = new XFormFieldImpl("jid"); XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
field.setType(FormField.TYPE_HIDDEN);
searchResults.addField(field);
field = new XFormFieldImpl("jid");
field.setLabel("JID"); field.setLabel("JID");
searchResults.addReportedField(field); searchResults.addReportedField(field);
...@@ -360,9 +379,7 @@ public class SearchPlugin implements Component, Plugin { ...@@ -360,9 +379,7 @@ public class SearchPlugin implements Component, Plugin {
searchResults.addReportedField(field); searchResults.addReportedField(field);
} }
Iterator userIter = users.iterator(); for (User user : users) {
while (userIter.hasNext()) {
User user = (User) userIter.next();
String username = user.getUsername(); String username = user.getUsername();
ArrayList<XFormFieldImpl> items = new ArrayList<XFormFieldImpl>(); ArrayList<XFormFieldImpl> items = new ArrayList<XFormFieldImpl>();
...@@ -395,13 +412,11 @@ public class SearchPlugin implements Component, Plugin { ...@@ -395,13 +412,11 @@ public class SearchPlugin implements Component, Plugin {
return replyPacket; return replyPacket;
} }
private IQ replyNonDataFormResult(List users, IQ packet) { private IQ replyNonDataFormResult(List<User> users, IQ packet) {
Element replyQuery = DocumentHelper.createElement(QName.get("query", "jabber:iq:search")); Element replyQuery = DocumentHelper.createElement(QName.get("query", "jabber:iq:search"));
String serverName = XMPPServer.getInstance().getServerInfo().getName(); String serverName = XMPPServer.getInstance().getServerInfo().getName();
Iterator userIter = users.iterator();
while (userIter.hasNext()) {
User user = (User) userIter.next();
for (User user : users) {
Element item = DocumentHelper.createElement("item"); Element item = DocumentHelper.createElement("item");
Attribute jib = DocumentHelper.createAttribute(item, "jid", user.getUsername() + "@" + serverName); Attribute jib = DocumentHelper.createAttribute(item, "jid", user.getUsername() + "@" + serverName);
item.add(jib); item.add(jib);
...@@ -419,6 +434,77 @@ public class SearchPlugin implements Component, Plugin { ...@@ -419,6 +434,77 @@ public class SearchPlugin implements Component, Plugin {
return replyPacket; return replyPacket;
} }
public String getServiceName() {
return serviceName;
}
public void setServiceName(String name) {
changeServiceName(name);
JiveGlobals.setProperty("plugin.search.serviceName", name);
}
public boolean getServiceEnabled() {
return serviceEnabled;
}
public void setServiceEnabled(boolean enabled) {
serviceEnabled = enabled;
JiveGlobals.setProperty("plugin.search.serviceEnabled", enabled ? "true" : "false");
}
public void propertySet(String property, Map params) {
if (property.equals("plugin.search.serviceEnabled")) {
this.serviceEnabled = Boolean.parseBoolean((String)params.get("value"));
}
else if (property.equals("plugin.search.serviceName")) {
changeServiceName((String)params.get("value"));
}
}
public void propertyDeleted(String property, Map params) {
if (property.equals("plugin.search.serviceEnabled")) {
this.serviceEnabled = true;
}
else if (property.equals("plugin.search.serviceName")) {
changeServiceName("search");
}
}
public void xmlPropertySet(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");
}
if (this.serviceName.equals(serviceName)) {
return;
}
// Re-register the service.
try {
componentManager.removeComponent(this.serviceName);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
try {
componentManager.addComponent(serviceName, this);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
this.serviceName = serviceName;
}
/** /**
* Returns the collection of field names that can be used to search for a * 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 * user. Typical fields are username, name, and email. These values can be
...@@ -447,9 +533,8 @@ public class SearchPlugin implements Component, Plugin { ...@@ -447,9 +533,8 @@ public class SearchPlugin implements Component, Plugin {
int index = query.indexOf("*"); int index = query.indexOf("*");
if (index == -1) { if (index == -1) {
Iterator users = userManager.getUsers().iterator(); Collection<User> users = userManager.getUsers();
while (users.hasNext()) { for (User user : users) {
User user = (User) users.next();
if (field.equals("Username")) { if (field.equals("Username")) {
try { try {
foundUsers.add(userManager.getUser(query)); foundUsers.add(userManager.getUser(query));
...@@ -475,10 +560,8 @@ public class SearchPlugin implements Component, Plugin { ...@@ -475,10 +560,8 @@ public class SearchPlugin implements Component, Plugin {
} }
else { else {
String prefix = query.substring(0, index); String prefix = query.substring(0, index);
Iterator users = userManager.getUsers().iterator(); Collection<User> users = userManager.getUsers();
while (users.hasNext()) { for (User user : users) {
User user = (User) users.next();
String userInfo = ""; String userInfo = "";
if (field.equals("Username")) { if (field.equals("Username")) {
userInfo = user.getUsername(); userInfo = user.getUsername();
......
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