Commit 33741004 authored by Ryan Graham's avatar Ryan Graham Committed by ryang

* fixed issue where a null pointer exception could occur when a LDAP <searchFilter> is being used

* replaced tab characters with spaces

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@3167 b35dd754-fafc-0310-a699-88a17e54d16e
parent a7b1d674
...@@ -44,6 +44,11 @@ ...@@ -44,6 +44,11 @@
Search Plugin Changelog Search Plugin Changelog
</h1> </h1>
<p><b>1.1.3</b> -- December 7, 2005</b></p>
<ul>
<li>Client Search - fixed issue where a null pointer exception could occur when a LDAP <searchFilter> is being used.
</ul>
<p><b>1.1.2</b> -- June 30, 2005</b></p> <p><b>1.1.2</b> -- June 30, 2005</b></p>
<ul> <ul>
<li>Admin Console - fixed possible null pointer exception when during a search. <li>Admin Console - fixed possible null pointer exception when during a search.
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<name>Search</name> <name>Search</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.1.2</version> <version>1.1.3</version>
<date>06/30/2005</date> <date>12/07/2005</date>
<minServerVersion>2.3.0</minServerVersion> <minServerVersion>2.3.0</minServerVersion>
<adminconsole> <adminconsole>
......
...@@ -17,6 +17,7 @@ import java.util.Hashtable; ...@@ -17,6 +17,7 @@ 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 java.util.Map;
import java.util.Set;
import org.dom4j.Attribute; import org.dom4j.Attribute;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
...@@ -59,6 +60,9 @@ import org.xmpp.packet.Packet; ...@@ -59,6 +60,9 @@ import org.xmpp.packet.Packet;
* @author Ryan Graham * @author Ryan Graham
*/ */
public class SearchPlugin implements Component, Plugin, PropertyEventListener { public class SearchPlugin implements Component, Plugin, PropertyEventListener {
public static final String PLUGIN_SEARCH_SERVICENAME = "plugin.search.serviceName";
public static final String PLUGIN_SEARCH_SERVICEENABLED = "plugin.search.serviceEnabled";
private XMPPServer server; private XMPPServer server;
private UserManager userManager; private UserManager userManager;
private ComponentManager componentManager; private ComponentManager componentManager;
...@@ -111,7 +115,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -111,7 +115,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
try { try {
componentManager.addComponent(serviceName, this); componentManager.addComponent(serviceName, this);
} }
catch (Exception e) { catch (Exception e) {
componentManager.getLog().error(e); componentManager.getLog().error(e);
} }
PropertyEventDispatcher.addListener(this); PropertyEventDispatcher.addListener(this);
...@@ -131,7 +135,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -131,7 +135,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
field.addValue("jabber:iq:search"); field.addValue("jabber:iq:search");
searchForm.addField(field); searchForm.addField(field);
field = new XFormFieldImpl("search"); 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);
...@@ -143,7 +147,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -143,7 +147,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
field = new XFormFieldImpl(searchField); field = new XFormFieldImpl(searchField);
field.setType(FormField.TYPE_BOOLEAN); field.setType(FormField.TYPE_BOOLEAN);
field.addValue("1"); field.addValue("1");
field.setLabel(searchField); field.setLabel(searchField);
field.setRequired(false); field.setRequired(false);
searchForm.addField(field); searchForm.addField(field);
...@@ -194,7 +198,6 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -194,7 +198,6 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
catch (ComponentException e) { catch (ComponentException e) {
componentManager.getLog().error(e); componentManager.getLog().error(e);
} }
} }
else if ("http://jabber.org/protocol/disco#info".equals(namespace)) { else if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
try { try {
...@@ -268,7 +271,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -268,7 +271,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
} }
private IQ processSetPacket(IQ packet) { private IQ processSetPacket(IQ packet) {
List<User> users = new ArrayList<User>(); Set<User> users = new HashSet<User>();
Element incomingForm = packet.getChildElement(); Element incomingForm = packet.getChildElement();
boolean isDataFormQuery = (incomingForm.element(QName.get("x", "jabber:x:data")) != null); boolean isDataFormQuery = (incomingForm.element(QName.get("x", "jabber:x:data")) != null);
...@@ -276,8 +279,8 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -276,8 +279,8 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
Hashtable<String, String> searchList = extractSearchQuery(incomingForm); Hashtable<String, String> searchList = extractSearchQuery(incomingForm);
Enumeration<String> searchIter = searchList.keys(); Enumeration<String> searchIter = searchList.keys();
while (searchIter.hasMoreElements()) { while (searchIter.hasMoreElements()) {
String field = (String) searchIter.nextElement(); String field = searchIter.nextElement();
String query = (String) searchList.get(field); String query = searchList.get(field);
Collection<User> foundUsers = new ArrayList<User>(); Collection<User> foundUsers = new ArrayList<User>();
if (userManager != null) { if (userManager != null) {
...@@ -290,9 +293,8 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -290,9 +293,8 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
foundUsers.addAll(findUsers(field, query)); foundUsers.addAll(findUsers(field, query));
} }
// Filter out all duplicate users.
for (User user : foundUsers) { for (User user : foundUsers) {
if (!users.contains(user)) { if (user != null) {
users.add(user); users.add(user);
} }
} }
...@@ -340,32 +342,32 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -340,32 +342,32 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
} }
} }
else { else {
List<String> searchFields = new ArrayList<String>(); List<String> searchFields = new ArrayList<String>();
String search = ""; String search = "";
Iterator fields = form.elementIterator("field"); Iterator fields = form.elementIterator("field");
while (fields.hasNext()) { while (fields.hasNext()) {
Element searchField = (Element) fields.next(); Element searchField = (Element) fields.next();
String field = searchField.attributeValue("var"); String field = searchField.attributeValue("var");
String value = searchField.element("value").getTextTrim(); String value = searchField.element("value").getTextTrim();
if (field.equals("search")) { if (field.equals("search")) {
search = value; search = value;
} }
else if (value.equals("1")) { else if (value.equals("1")) {
searchFields.add(field); searchFields.add(field);
} }
} }
for (String field : searchFields) { for (String field : searchFields) {
searchList.put(field, search); searchList.put(field, search);
} }
} }
return searchList; return searchList;
} }
private IQ replyDataFormResult(List<User> users, IQ packet) { private IQ replyDataFormResult(Set<User> users, IQ packet) {
XDataFormImpl searchResults = new XDataFormImpl(DataForm.TYPE_RESULT); XDataFormImpl searchResults = new XDataFormImpl(DataForm.TYPE_RESULT);
XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE"); XFormFieldImpl field = new XFormFieldImpl("FORM_TYPE");
...@@ -415,7 +417,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -415,7 +417,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
return replyPacket; return replyPacket;
} }
private IQ replyNonDataFormResult(List<User> users, IQ packet) { private IQ replyNonDataFormResult(Set<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();
...@@ -443,7 +445,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -443,7 +445,7 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
public void setServiceName(String name) { public void setServiceName(String name) {
changeServiceName(name); changeServiceName(name);
JiveGlobals.setProperty("plugin.search.serviceName", name); JiveGlobals.setProperty(PLUGIN_SEARCH_SERVICENAME, name);
} }
public boolean getServiceEnabled() { public boolean getServiceEnabled() {
...@@ -452,23 +454,23 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener { ...@@ -452,23 +454,23 @@ public class SearchPlugin implements Component, Plugin, PropertyEventListener {
public void setServiceEnabled(boolean enabled) { public void setServiceEnabled(boolean enabled) {
serviceEnabled = enabled; serviceEnabled = enabled;
JiveGlobals.setProperty("plugin.search.serviceEnabled", enabled ? "true" : "false"); JiveGlobals.setProperty(PLUGIN_SEARCH_SERVICEENABLED, enabled ? "true" : "false");
} }
public void propertySet(String property, Map params) { public void propertySet(String property, Map params) {
if (property.equals("plugin.search.serviceEnabled")) { if (property.equals(PLUGIN_SEARCH_SERVICEENABLED)) {
this.serviceEnabled = Boolean.parseBoolean((String)params.get("value")); this.serviceEnabled = Boolean.parseBoolean((String)params.get("value"));
} }
else if (property.equals("plugin.search.serviceName")) { else if (property.equals(PLUGIN_SEARCH_SERVICENAME)) {
changeServiceName((String)params.get("value")); changeServiceName((String)params.get("value"));
} }
} }
public void propertyDeleted(String property, Map params) { public void propertyDeleted(String property, Map params) {
if (property.equals("plugin.search.serviceEnabled")) { if (property.equals(PLUGIN_SEARCH_SERVICEENABLED)) {
this.serviceEnabled = true; this.serviceEnabled = true;
} }
else if (property.equals("plugin.search.serviceName")) { else if (property.equals(PLUGIN_SEARCH_SERVICENAME)) {
changeServiceName("search"); changeServiceName("search");
} }
} }
......
...@@ -25,71 +25,70 @@ ...@@ -25,71 +25,70 @@
Set<String> searchFields = userManager.getSearchFields(); Set<String> searchFields = userManager.getSearchFields();
List<String> selectedFields = new ArrayList<String>(); List<String> selectedFields = new ArrayList<String>();
List<User> users = new ArrayList<User>(); Set<User> users = new HashSet<User>();
if (criteria != null) { if (criteria != null) {
for (String searchField : searchFields) { for (String searchField : searchFields) {
boolean searchValue = ParamUtils.getBooleanParameter(request, searchField, false); boolean searchValue = ParamUtils.getBooleanParameter(request, searchField, false);
if (!moreOptions || searchValue) { if (!moreOptions || searchValue) {
selectedFields.add(searchField); selectedFields.add(searchField);
Collection<User> foundUsers = userManager.findUsers(new HashSet<String>(Arrays.asList(searchField)), criteria); Collection<User> foundUsers = userManager.findUsers(new HashSet<String>(Arrays.asList(searchField)), criteria);
//filter out duplicate users for (User user : foundUsers) {
for (User user : foundUsers) { if (user != null) {
if (!users.contains(user)) { users.add(user);
users.add(user); }
} }
}
} }
} }
} }
%> %>
<form name="f" action="advance-user-search.jsp"> <form name="f" action="advance-user-search.jsp">
<input type="hidden" name="search" value="true"/> <input type="hidden" name="search" value="true"/>
<input type="hidden" name="moreOptions" value="<%=moreOptions %>"/> <input type="hidden" name="moreOptions" value="<%=moreOptions %>"/>
<fieldset> <fieldset>
<legend><fmt:message key="user.search.search_user" /></legend> <legend><fmt:message key="user.search.search_user" /></legend>
<div> <div>
<table cellpadding="3" cellspacing="1" border="0" width="600"> <table cellpadding="3" cellspacing="1" border="0" width="600">
<tr class="c1"> <tr class="c1">
<td width="1%" colspan="2" nowrap> <td width="1%" colspan="2" nowrap>
Search: Search:
&nbsp;<input type="text" name="criteria" value="<%=(criteria != null ? criteria : "") %>" size="30" maxlength="75"/> &nbsp;<input type="text" name="criteria" value="<%=(criteria != null ? criteria : "") %>" size="30" maxlength="75"/>
&nbsp;<input type="submit" name="search" value="<fmt:message key="user.search.search" />"/> &nbsp;<input type="submit" name="search" value="<fmt:message key="user.search.search" />"/>
</td> </td>
</tr> </tr>
<% if (moreOptions) { %> <% if (moreOptions) { %>
<tr class="c1"> <tr class="c1">
<td width="1%" colspan="2" nowrap>Wildcard (*) characters are allowed as part the of query. The following fields are available for searching:</td> <td width="1%" colspan="2" nowrap>Wildcard (*) characters are allowed as part the of query. The following fields are available for searching:</td>
</tr> </tr>
<% for (String searchField : searchFields) { %> <% for (String searchField : searchFields) { %>
<tr class="c1"> <tr class="c1">
<td width="1%" nowrap><%=searchField %>:</td> <td width="1%" nowrap><%=searchField %>:</td>
<td class="c2"> <td class="c2">
<% if (criteria == null) { %> <% if (criteria == null) { %>
<input type="checkbox" checked name="<%=searchField %>"/> <input type="checkbox" checked name="<%=searchField %>"/>
<% } else { %> <% } else { %>
<input type="checkbox" <%=selectedFields.contains(searchField) ? "checked" : "" %> name="<%=searchField %>"/> <input type="checkbox" <%=selectedFields.contains(searchField) ? "checked" : "" %> name="<%=searchField %>"/>
<% } %> <% } %>
</td> </td>
</tr> </tr>
<% } %> <% } %>
<tr> <tr>
<td nowrap>&raquo;&nbsp;<a href="advance-user-search.jsp?moreOptions=false">Less Options</a></td> <td nowrap>&raquo;&nbsp;<a href="advance-user-search.jsp?moreOptions=false">Less Options</a></td>
</tr> </tr>
<% } else { %> <% } else { %>
<tr> <tr>
<td nowrap>&raquo;&nbsp;<a href="advance-user-search.jsp?moreOptions=true">More Options</a></td> <td nowrap>&raquo;&nbsp;<a href="advance-user-search.jsp?moreOptions=true">More Options</a></td>
</tr> </tr>
<% } %> <% } %>
</table> </table>
</div> </div>
</fieldset> </fieldset>
</form> </form>
<% if (criteria != null) { %> <% if (criteria != null) { %>
...@@ -112,71 +111,73 @@ Users Found: <%=users.size() %> ...@@ -112,71 +111,73 @@ Users Found: <%=users.size() %>
</thead> </thead>
<tbody> <tbody>
<% if (users.isEmpty()) { %> <% if (users.isEmpty()) { %>
<tr> <tr>
<td align="center" colspan="7"><fmt:message key="user.summary.not_user" /></td> <td align="center" colspan="7"><fmt:message key="user.summary.not_user" /></td>
</tr> </tr>
<% <%
} else { } else {
int i = 0; int i = 0;
PresenceManager presenceManager = XMPPServer.getInstance().getPresenceManager(); PresenceManager presenceManager = XMPPServer.getInstance().getPresenceManager();
for (User user : users) { for (User user : users) {
i++; i++;
%> %>
<tr class="jive-<%= (((i%2)==0) ? "even" : "odd") %>"> <tr class="jive-<%= (((i%2)==0) ? "even" : "odd") %>">
<td width="1%"> <td width="1%">
<%= i %> <%= i %>
</td> </td>
<td width="1%" align="center" valign="middle"> <td width="1%" align="center" valign="middle">
<% if (presenceManager.isAvailable(user)) { <% if (presenceManager.isAvailable(user)) {
Presence presence = presenceManager.getPresence(user); Presence presence = presenceManager.getPresence(user);
%>
<% if (presence.getShow() == null) { %> if (presence.getShow() == null) {
<img src="images/user-green-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="user.properties.available" />"> %> <img src="images/user-green-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="user.properties.available" />"> <%
<% } %> }
<% if (presence.getShow() == Presence.Show.chat) { %>
<img src="images/user-green-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.chat_available" />"> if (presence.getShow() == Presence.Show.chat) {
<% } %> %> <img src="images/user-green-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.chat_available" />"> <%
<% if (presence.getShow() == Presence.Show.away) { %> }
<img src="images/user-yellow-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.away" />">
<% } %> if (presence.getShow() == Presence.Show.away) {
<% if (presence.getShow() == Presence.Show.xa) { %> %> <img src="images/user-yellow-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.away" />"> <%
<img src="images/user-yellow-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.extended" />"> }
<% } %>
<% if (presence.getShow() == Presence.Show.dnd) { %> if (presence.getShow() == Presence.Show.xa) {
<img src="images/user-red-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.not_disturb" />"> %> <img src="images/user-yellow-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.extended" />"> <%
<% } %> }
<% } else { %> if (presence.getShow() == Presence.Show.dnd) {
%> <img src="images/user-red-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="session.details.not_disturb" />"> <%
<img src="images/user-clear-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="user.properties.offline" />"> }
} else {
<% } %> %> <img src="images/user-clear-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="user.properties.offline" />"> <%
</td> }
<td width="30%"> %>
<a href="../../user-properties.jsp?username=<%= URLEncoder.encode(user.getUsername(), "UTF-8") %>"><%= user.getUsername() %></a> </td>
</td> <td width="30%">
<td width="35"> <a href="../../user-properties.jsp?username=<%= URLEncoder.encode(user.getUsername(), "UTF-8") %>"><%= user.getUsername() %></a>
<%= user.getName() %> &nbsp; </td>
</td> <td width="35">
<td width="35%"> <%= user.getName() %> &nbsp;
<%= user.getEmail() %> &nbsp; </td>
</td> <td width="35%">
<td width="1%" align="center"> <%= user.getEmail() %> &nbsp;
<a href="../../user-edit-form.jsp?username=<%= URLEncoder.encode(user.getUsername(), "UTF-8") %>" </td>
title="<fmt:message key="global.click_edit" />" <td width="1%" align="center">
><img src="images/edit-16x16.gif" width="17" height="17" border="0"></a> <a href="../../user-edit-form.jsp?username=<%= URLEncoder.encode(user.getUsername(), "UTF-8") %>"
</td> title="<fmt:message key="global.click_edit" />"
<td width="1%" align="center" style="border-right:1px #ccc solid;"> ><img src="images/edit-16x16.gif" width="17" height="17" border="0"></a>
<a href="../../user-delete.jsp?username=<%= URLEncoder.encode(user.getUsername(), "UTF-8") %>" </td>
title="<fmt:message key="global.click_delete" />" <td width="1%" align="center" style="border-right:1px #ccc solid;">
><img src="images/delete-16x16.gif" width="16" height="16" border="0"></a> <a href="../../user-delete.jsp?username=<%= URLEncoder.encode(user.getUsername(), "UTF-8") %>"
</td> title="<fmt:message key="global.click_delete" />"
</tr> ><img src="images/delete-16x16.gif" width="16" height="16" border="0"></a>
</td>
</tr>
<% <%
} }
} }
%> %>
......
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