UserSearch.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.search;

  18. import java.io.IOException;

  19. import org.jivesoftware.smack.SmackException.NoResponseException;
  20. import org.jivesoftware.smack.SmackException.NotConnectedException;
  21. import org.jivesoftware.smack.XMPPConnection;
  22. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  23. import org.jivesoftware.smack.packet.IQ;
  24. import org.jivesoftware.smack.packet.IqData;
  25. import org.jivesoftware.smack.packet.SimpleIQ;
  26. import org.jivesoftware.smack.packet.XmlEnvironment;
  27. import org.jivesoftware.smack.parsing.SmackParsingException;
  28. import org.jivesoftware.smack.provider.IqProvider;
  29. import org.jivesoftware.smack.util.PacketParserUtils;
  30. import org.jivesoftware.smack.xml.XmlPullParser;
  31. import org.jivesoftware.smack.xml.XmlPullParserException;

  32. import org.jivesoftware.smackx.xdata.packet.DataForm;

  33. import org.jxmpp.jid.DomainBareJid;

  34. /**
  35.  * Implements the protocol currently used to search information repositories on the Jabber network. To date, the jabber:iq:search protocol
  36.  * has been used mainly to search for people who have registered with user directories (e.g., the "Jabber User Directory" hosted at users.jabber.org).
  37.  * However, the jabber:iq:search protocol is not limited to user directories, and could be used to search other Jabber information repositories
  38.  * (such as chatroom directories) or even to provide a Jabber interface to conventional search engines.
  39.  *
  40.  * The basic functionality is to query an information repository regarding the possible search fields, to send a search query, and to receive search results.
  41.  *
  42.  * @author Derek DeMoro
  43.  */
  44. public class UserSearch extends SimpleIQ {

  45.     public static final String ELEMENT = QUERY_ELEMENT;
  46.     public static final String NAMESPACE = "jabber:iq:search";

  47.     /**
  48.      * Creates a new instance of UserSearch.
  49.      */
  50.     public UserSearch() {
  51.         super(ELEMENT, NAMESPACE);
  52.     }

  53.     /**
  54.      * Returns the form for all search fields supported by the search service.
  55.      *
  56.      * @param con           the current XMPPConnection.
  57.      * @param searchService the search service to use. (ex. search.jivesoftware.com)
  58.      * @return the search form received by the server.
  59.      * @throws XMPPErrorException if there was an XMPP error returned.
  60.      * @throws NoResponseException if there was no response from the remote entity.
  61.      * @throws NotConnectedException if the XMPP connection is not connected.
  62.      * @throws InterruptedException if the calling thread was interrupted.
  63.      */
  64.     public DataForm getSearchForm(XMPPConnection con, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  65.         UserSearch search = new UserSearch();
  66.         search.setType(IQ.Type.get);
  67.         search.setTo(searchService);

  68.         IQ response = con.sendIqRequestAndWaitForResponse(search);
  69.         return DataForm.from(response, NAMESPACE);
  70.     }

  71.     /**
  72.      * Sends the filled out answer form to be sent and queried by the search service.
  73.      *
  74.      * @param con           the current XMPPConnection.
  75.      * @param searchForm    the <code>Form</code> to send for querying.
  76.      * @param searchService the search service to use. (ex. search.jivesoftware.com)
  77.      * @return ReportedData the data found from the query.
  78.      * @throws XMPPErrorException if there was an XMPP error returned.
  79.      * @throws NoResponseException if there was no response from the remote entity.
  80.      * @throws NotConnectedException if the XMPP connection is not connected.
  81.      * @throws InterruptedException if the calling thread was interrupted.
  82.      */
  83.     public ReportedData sendSearchForm(XMPPConnection con, DataForm searchForm, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  84.         UserSearch search = new UserSearch();
  85.         search.setType(IQ.Type.set);
  86.         search.setTo(searchService);
  87.         search.addExtension(searchForm);

  88.         IQ response = con.sendIqRequestAndWaitForResponse(search);
  89.         return ReportedData.getReportedDataFrom(response);
  90.     }

  91.     /**
  92.      * Sends the filled out answer form to be sent and queried by the search service.
  93.      *
  94.      * @param con           the current XMPPConnection.
  95.      * @param searchForm    the <code>Form</code> to send for querying.
  96.      * @param searchService the search service to use. (ex. search.jivesoftware.com)
  97.      * @return ReportedData the data found from the query.
  98.      * @throws XMPPErrorException if there was an XMPP error returned.
  99.      * @throws NoResponseException if there was no response from the remote entity.
  100.      * @throws NotConnectedException if the XMPP connection is not connected.
  101.      * @throws InterruptedException if the calling thread was interrupted.
  102.      */
  103.     public ReportedData sendSimpleSearchForm(XMPPConnection con, DataForm searchForm, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  104.         SimpleUserSearch search = new SimpleUserSearch();
  105.         search.setForm(searchForm);
  106.         search.setType(IQ.Type.set);
  107.         search.setTo(searchService);

  108.         SimpleUserSearch response = con.sendIqRequestAndWaitForResponse(search);
  109.         return response.getReportedData();
  110.     }

  111.     /**
  112.      * Internal Search service Provider.
  113.      */
  114.     public static class Provider extends IqProvider<IQ> {

  115.         // FIXME this provider does return two different types of IQs
  116.         @Override
  117.         public IQ parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
  118.             UserSearch search = null;
  119.             SimpleUserSearch simpleUserSearch = new SimpleUserSearch();

  120.             boolean done = false;
  121.             while (!done) {
  122.                 XmlPullParser.Event eventType = parser.next();
  123.                 if (eventType == XmlPullParser.Event.START_ELEMENT && parser.getName().equals("item")) {
  124.                     simpleUserSearch.parseItems(parser);
  125.                     return simpleUserSearch;
  126.                 }
  127.                 else if (eventType == XmlPullParser.Event.START_ELEMENT && parser.getNamespace().equals("jabber:x:data")) {
  128.                     // Otherwise, it must be a packet extension.
  129.                     search = new UserSearch();
  130.                     PacketParserUtils.addExtensionElement(search, parser, xmlEnvironment);
  131.                 }
  132.                 else if (eventType == XmlPullParser.Event.END_ELEMENT) {
  133.                     if (parser.getName().equals("query")) {
  134.                         done = true;
  135.                     }
  136.                 }
  137.             }

  138.             if (search != null) {
  139.                 return search;
  140.             }
  141.             return simpleUserSearch;
  142.         }
  143.     }

  144. }