001/**
002 *
003 * Copyright 2003-2007 Jive Software.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.search;
018
019import org.jivesoftware.smack.SmackException.NoResponseException;
020import org.jivesoftware.smack.SmackException.NotConnectedException;
021import org.jivesoftware.smack.XMPPConnection;
022import org.jivesoftware.smack.XMPPException;
023import org.jivesoftware.smack.XMPPException.XMPPErrorException;
024import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
025import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
026import org.jivesoftware.smackx.disco.packet.DiscoverItems;
027import org.jivesoftware.smackx.xdata.Form;
028
029import java.util.ArrayList;
030import java.util.Collection;
031import java.util.List;
032
033/**
034 * The UserSearchManager is a facade built upon Jabber Search Services (XEP-055) to allow for searching
035 * repositories on a Jabber Server. This implementation allows for transparency of implementation of
036 * searching (DataForms or No DataForms), but allows the user to simply use the DataForm model for both
037 * types of support.
038 * <pre>
039 * XMPPConnection con = new XMPPTCPConnection("jabber.org");
040 * con.login("john", "doe");
041 * UserSearchManager search = new UserSearchManager(con, "users.jabber.org");
042 * Form searchForm = search.getSearchForm();
043 * Form answerForm = searchForm.createAnswerForm();
044 * answerForm.setAnswer("last", "DeMoro");
045 * ReportedData data = search.getSearchResults(answerForm);
046 * // Use Returned Data
047 * </pre>
048 *
049 * @author Derek DeMoro
050 */
051public class UserSearchManager {
052
053    private XMPPConnection con;
054    private UserSearch userSearch;
055
056    /**
057     * Creates a new UserSearchManager.
058     *
059     * @param con the XMPPConnection to use.
060     */
061    public UserSearchManager(XMPPConnection con) {
062        this.con = con;
063        userSearch = new UserSearch();
064    }
065
066    /**
067     * Returns the form to fill out to perform a search.
068     *
069     * @param searchService the search service to query.
070     * @return the form to fill out to perform a search.
071     * @throws XMPPErrorException 
072     * @throws NoResponseException 
073     * @throws NotConnectedException 
074     */
075    public Form getSearchForm(String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException  {
076        return userSearch.getSearchForm(con, searchService);
077    }
078
079    /**
080     * Submits a search form to the server and returns the resulting information
081     * in the form of <code>ReportedData</code>
082     *
083     * @param searchForm    the <code>Form</code> to submit for searching.
084     * @param searchService the name of the search service to use.
085     * @return the ReportedData returned by the server.
086     * @throws XMPPErrorException 
087     * @throws NoResponseException 
088     * @throws NotConnectedException 
089     */
090    public ReportedData getSearchResults(Form searchForm, String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException  {
091        return userSearch.sendSearchForm(con, searchForm, searchService);
092    }
093
094
095    /**
096     * Returns a collection of search services found on the server.
097     *
098     * @return a Collection of search services found on the server.
099     * @throws XMPPErrorException 
100     * @throws NoResponseException 
101     * @throws NotConnectedException 
102     */
103    public Collection<String> getSearchServices() throws NoResponseException, XMPPErrorException, NotConnectedException  {
104        final List<String> searchServices = new ArrayList<String>();
105        ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(con);
106        DiscoverItems items = discoManager.discoverItems(con.getServiceName());
107        for (DiscoverItems.Item item : items.getItems()) {
108            try {
109                DiscoverInfo info;
110                try {
111                    info = discoManager.discoverInfo(item.getEntityID());
112                }
113                catch (XMPPException e) {
114                    // Ignore Case
115                    continue;
116                }
117
118                if (info.containsFeature("jabber:iq:search")) {
119                    searchServices.add(item.getEntityID());
120                }
121            }
122            catch (Exception e) {
123                // No info found.
124                break;
125            }
126        }
127        return searchServices;
128    }
129}