searchplugin.java
来自「基于Jabber协议的即时消息服务器」· Java 代码 · 共 611 行 · 第 1/2 页
JAVA
611 行
/**
* Copyright (C) 2005 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.wildfire.plugin;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.QName;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.PropertyEventDispatcher;
import org.jivesoftware.util.PropertyEventListener;
import org.jivesoftware.wildfire.XMPPServer;
import org.jivesoftware.wildfire.container.Plugin;
import org.jivesoftware.wildfire.container.PluginManager;
import org.jivesoftware.wildfire.forms.DataForm;
import org.jivesoftware.wildfire.forms.FormField;
import org.jivesoftware.wildfire.forms.spi.XDataFormImpl;
import org.jivesoftware.wildfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.wildfire.user.User;
import org.jivesoftware.wildfire.user.UserManager;
import org.jivesoftware.wildfire.user.UserNotFoundException;
import org.xmpp.component.Component;
import org.xmpp.component.ComponentException;
import org.xmpp.component.ComponentManager;
import org.xmpp.component.ComponentManagerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketError;
import java.io.File;
import java.util.*;
/**
* Provides support for Jabber Search
* (<a href="http://www.jabber.org/jeps/jep-0055.html">JEP-0055</a>).<p>
*
* The basic functionality is to query an information repository
* regarding the possible search fields, to send a search query,
* and to receive search results. This implementation was primarily designed to use
* <a href="http://www.jabber.org/jeps/jep-0004.html">Data Forms</a>, but
* also supports non-dataform searches.
* <p/>
*
* @author Ryan Graham
*/
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 UserManager userManager;
private ComponentManager componentManager;
private PluginManager pluginManager;
private String serviceName;
private boolean serviceEnabled;
private static String serverName;
private static String instructions = "The following fields are available for search. "
+ "Wildcard (*) characters are allowed as part of the query.";
private static Element probeResult;
private Collection<String> searchFields;
private TreeMap<String, String> fieldLookup = new TreeMap<String, String>(new CaseInsensitiveComparator());
private Map<String, String> reverseFieldLookup = new HashMap<String, String>();
public SearchPlugin() {
serviceName = JiveGlobals.getProperty("plugin.search.serviceName", "search");
serviceEnabled = JiveGlobals.getBooleanProperty("plugin.search.serviceEnabled", true);
serverName = XMPPServer.getInstance().getServerInfo().getName();
// See if the installed provider supports searching. If not, workaround
// by providing our own searching.
UserManager manager = UserManager.getInstance();
try {
searchFields = manager.getSearchFields();
userManager = UserManager.getInstance();
searchFields = userManager.getSearchFields();
}
catch (UnsupportedOperationException uoe) {
// Use a SearchPluginUserManager instead.
searchFields = getSearchFields();
}
fieldLookup.put("jid", "Username");
fieldLookup.put("username", "Username");
fieldLookup.put("first", "Name");
fieldLookup.put("last", "Name");
fieldLookup.put("nick", "Name");
fieldLookup.put("name", "Name");
fieldLookup.put("email", "Email");
}
public String getName() {
return pluginManager.getName(this);
}
public String getDescription() {
return pluginManager.getDescription(this);
}
public void initializePlugin(PluginManager manager, File pluginDirectory) {
pluginManager = manager;
componentManager = ComponentManagerFactory.getComponentManager();
try {
componentManager.addComponent(serviceName, this);
}
catch (Exception e) {
componentManager.getLog().error(e);
}
PropertyEventDispatcher.addListener(this);
if (probeResult == null) {
probeResult = DocumentHelper.createElement(QName.get("query", "jabber:iq:search"));
//non-data form
probeResult.addElement("instructions").addText(instructions);
XDataFormImpl searchForm = new XDataFormImpl(DataForm.TYPE_FORM);
searchForm.setTitle("User Search");
searchForm.addInstruction(instructions);
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.setLabel("Search");
field.setRequired(true);
searchForm.addField(field);
for (String searchField : searchFields) {
//non-data form
probeResult.addElement(searchField);
field = new XFormFieldImpl(searchField);
field.setType(FormField.TYPE_BOOLEAN);
field.addValue("1");
field.setLabel(searchField);
field.setRequired(false);
searchForm.addField(field);
}
probeResult.add(searchForm.asXMLElement());
}
}
public void initialize(JID jid, ComponentManager componentManager) {
}
public void start() {
}
public void destroyPlugin() {
PropertyEventDispatcher.removeListener(this);
pluginManager = null;
try {
componentManager.removeComponent(serviceName);
componentManager = null;
}
catch (Exception e) {
componentManager.getLog().error(e);
}
userManager = null;
fieldLookup = null;
reverseFieldLookup = null;
}
public void shutdown() {
}
public void processPacket(Packet p) {
if (p instanceof IQ) {
IQ packet = (IQ) p;
Element childElement = (packet).getChildElement();
String namespace = null;
if (childElement != null) {
namespace = childElement.getNamespaceURI();
}
if ("jabber:iq:search".equals(namespace)) {
try {
IQ replyPacket = handleIQ(packet);
if (replyPacket != null) {
componentManager.sendPacket(this, replyPacket);
}
}
catch (ComponentException e) {
componentManager.getLog().error(e);
}
}
else if ("http://jabber.org/protocol/disco#info".equals(namespace)) {
try {
IQ replyPacket = IQ.createResultIQ(packet);
Element responseElement = replyPacket
.setChildElement("query", "http://jabber.org/protocol/disco#info");
responseElement.addElement("identity").addAttribute("category", "search")
.addAttribute("type", "text")
.addAttribute("name", "User Search");
responseElement.addElement("feature").addAttribute("var", "jabber:iq:search");
componentManager.sendPacket(this, replyPacket);
}
catch (ComponentException e) {
componentManager.getLog().error(e);
}
}
else if ("http://jabber.org/protocol/disco#items".equals(namespace)) {
try {
IQ replyPacket = IQ.createResultIQ(packet);
replyPacket.setChildElement("query", "http://jabber.org/protocol/disco#items");
componentManager.sendPacket(this, replyPacket);
}
catch (ComponentException e) {
componentManager.getLog().error(e);
}
}
}
}
private IQ handleIQ(IQ packet) {
if (!serviceEnabled) {
return replyDisabled(packet);
}
if (IQ.Type.get.equals(packet.getType())) {
return processGetPacket(packet);
}
else if (IQ.Type.set.equals(packet.getType())) {
return processSetPacket(packet);
} else
if (IQ.Type.result.equals(packet.getType()) || IQ.Type.error.equals(packet.getType())) {
// Ignore
}
else {
// Unknown type was sent so
IQ reply = new IQ(IQ.Type.error, packet.getID());
reply.setFrom(packet.getTo());
reply.setTo(packet.getFrom());
reply.setError(PacketError.Condition.bad_request);
return reply;
}
return null;
}
private IQ replyDisabled(IQ packet) {
IQ replyPacket = IQ.createResultIQ(packet);
Element reply = replyPacket.setChildElement("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());
return replyPacket;
}
private IQ processGetPacket(IQ packet) {
IQ replyPacket = IQ.createResultIQ(packet);
replyPacket.setChildElement(probeResult.createCopy());
return replyPacket;
}
private IQ processSetPacket(IQ packet) {
Set<User> users = new HashSet<User>();
Element incomingForm = packet.getChildElement();
boolean isDataFormQuery = (incomingForm.element(QName.get("x", "jabber:x:data")) != null);
Hashtable<String, String> searchList = extractSearchQuery(incomingForm);
Enumeration<String> searchIter = searchList.keys();
while (searchIter.hasMoreElements()) {
String field = searchIter.nextElement();
String query = searchList.get(field);
Collection<User> foundUsers = new ArrayList<User>();
if (userManager != null) {
if (query.length() > 0 && !query.equals("jabber:iq:search")) {
foundUsers.addAll(userManager.findUsers(new HashSet<String>(
Arrays.asList((field))), query));
}
}
else {
foundUsers.addAll(findUsers(field, query));
}
for (User user : foundUsers) {
if (user != null) {
users.add(user);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?