11/**
22 *
3- * Copyright 2003-2007 Jive Software.
3+ * Copyright 2003-2007 Jive Software, 2025 Florian Schmaus .
44 *
55 * Licensed under the Apache License, Version 2.0 (the "License");
66 * you may not use this file except in compliance with the License.
1717package org .jivesoftware .smackx .search ;
1818
1919import java .util .List ;
20+ import java .util .Map ;
21+ import java .util .WeakHashMap ;
2022
23+ import org .jivesoftware .smack .Manager ;
2124import org .jivesoftware .smack .SmackException .NoResponseException ;
2225import org .jivesoftware .smack .SmackException .NotConnectedException ;
2326import org .jivesoftware .smack .XMPPConnection ;
2427import org .jivesoftware .smack .XMPPException .XMPPErrorException ;
28+ import org .jivesoftware .smack .packet .IQ ;
2529
2630import org .jivesoftware .smackx .disco .ServiceDiscoveryManager ;
2731import org .jivesoftware .smackx .xdata .form .FillableForm ;
3640 * searching (DataForms or No DataForms), but allows the user to simply use the DataForm model for both
3741 * types of support.
3842 * <pre>
39- * XMPPConnection con = new XMPPTCPConnection("jabber.org");
40- * con.login("john", "doe");
41- * UserSearchManager search = new UserSearchManager(con, "users.jabber.org");
42- * Form searchForm = search.getSearchForm();
43- * FillableForm answerForm = searchForm.getFillableForm()
44- * // Fill out the form.
45- * answerForm.setAnswer("last", "DeMoro");
46- * ReportedData data = search.getSearchResults(answerForm);
47- * // Use Returned Data
43+ * XMPPConnection connection = …;
44+ * var searchService = UserSearchManager.getSearchServices(connection).get(0);
45+ * var searchManager = UserSearchManager.getInstanceFor(connection);
46+ * var sarchForm = searchManager.getSearchForm(searchService);
47+ * var fillableForm = searchForm.getFillableForm();
48+ *
49+ * // Check for the required fields in the form and fill them
50+ * fillableForm.setAnswer("search", "John");
51+ *
52+ * var results = searchOne.search(fillableForm, userSearchService);
53+ * // Use results
4854 * </pre>
4955 *
5056 * @author Derek DeMoro
5157 */
52- public class UserSearchManager {
58+ public final class UserSearchManager extends Manager {
5359
54- private final XMPPConnection con ;
55- private final UserSearch userSearch ;
60+ private static final Map <XMPPConnection , UserSearchManager > INSTANCES = new WeakHashMap <>();
5661
62+ public static synchronized UserSearchManager getInstanceFor (XMPPConnection connection ) {
63+ var userSearchManager = INSTANCES .get (connection );
64+ if (userSearchManager == null ) {
65+ userSearchManager = new UserSearchManager (connection );
66+ INSTANCES .put (connection , userSearchManager );
67+ }
68+ return userSearchManager ;
69+ }
5770 /**
5871 * Creates a new UserSearchManager.
5972 *
60- * @param con the XMPPConnection to use.
73+ * @param connection the XMPPConnection to use.
6174 */
62- public UserSearchManager (XMPPConnection con ) {
63- this .con = con ;
64- userSearch = new UserSearch ();
75+ private UserSearchManager (XMPPConnection connection ) {
76+ super (connection );
6577 }
6678
6779 /**
@@ -75,39 +87,70 @@ public UserSearchManager(XMPPConnection con) {
7587 * @throws InterruptedException if the calling thread was interrupted.
7688 */
7789 public Form getSearchForm (DomainBareJid searchService ) throws NoResponseException , XMPPErrorException , NotConnectedException , InterruptedException {
78- DataForm dataForm = userSearch .getSearchForm (con , searchService );
90+ UserSearch search = new UserSearch ();
91+ search .setType (IQ .Type .get );
92+ search .setTo (searchService );
93+
94+ IQ response = connection ().sendIqRequestAndWaitForResponse (search );
95+ var dataForm = DataForm .from (response , UserSearch .NAMESPACE );
7996 return new Form (dataForm );
8097 }
8198
8299 /**
83- * Submits a search form to the server and returns the resulting information
84- * in the form of <code>ReportedData</code>.
100+ * Sends the filled out answer form to be sent and queried by the search service.
85101 *
86- * @param searchForm the <code>Form</code> to submit for searching .
87- * @param searchService the name of the search service to use.
88- * @return the ReportedData returned by the server .
102+ * @param filledForm the filled form with the query instructions .
103+ * @param searchService the search service to use. (ex. search.jivesoftware.com)
104+ * @return ReportedData the data found from the query .
89105 * @throws XMPPErrorException if there was an XMPP error returned.
90106 * @throws NoResponseException if there was no response from the remote entity.
91107 * @throws NotConnectedException if the XMPP connection is not connected.
92108 * @throws InterruptedException if the calling thread was interrupted.
93109 */
94- public ReportedData getSearchResults (FillableForm searchForm , DomainBareJid searchService )
110+ public ReportedData search (FillableForm filledForm , DomainBareJid searchService )
95111 throws NoResponseException , XMPPErrorException , NotConnectedException , InterruptedException {
96- DataForm dataForm = searchForm .getDataFormToSubmit ();
97- return userSearch .sendSearchForm (con , dataForm , searchService );
112+ UserSearch search = new UserSearch ();
113+ search .setType (IQ .Type .set );
114+ search .setTo (searchService );
115+ search .addExtension (filledForm .getDataFormToSubmit ());
116+
117+ IQ response = connection ().sendIqRequestAndWaitForResponse (search );
118+ return ReportedData .getReportedDataFrom (response );
119+ }
120+
121+ /**
122+ * Sends the filled out answer form to be sent and queried by the search service.
123+ *
124+ * @param searchForm the <code>Form</code> to send for querying.
125+ * @param searchService the search service to use. (ex. search.jivesoftware.com)
126+ * @return ReportedData the data found from the query.
127+ * @throws XMPPErrorException if there was an XMPP error returned.
128+ * @throws NoResponseException if there was no response from the remote entity.
129+ * @throws NotConnectedException if the XMPP connection is not connected.
130+ * @throws InterruptedException if the calling thread was interrupted.
131+ */
132+ public ReportedData sendSimpleSearchForm (DataForm searchForm , DomainBareJid searchService ) throws NoResponseException , XMPPErrorException , NotConnectedException , InterruptedException {
133+ SimpleUserSearch search = new SimpleUserSearch ();
134+ search .setForm (searchForm );
135+ search .setType (IQ .Type .set );
136+ search .setTo (searchService );
137+
138+ SimpleUserSearch response = connection ().sendIqRequestAndWaitForResponse (search );
139+ return response .getReportedData ();
98140 }
99141
100142 /**
101143 * Returns a collection of search services found on the server.
102144 *
145+ * @param connection the connection to query for search services.
103146 * @return a Collection of search services found on the server.
104147 * @throws XMPPErrorException if there was an XMPP error returned.
105148 * @throws NoResponseException if there was no response from the remote entity.
106149 * @throws NotConnectedException if the XMPP connection is not connected.
107150 * @throws InterruptedException if the calling thread was interrupted.
108151 */
109- public List <DomainBareJid > getSearchServices () throws NoResponseException , XMPPErrorException , NotConnectedException , InterruptedException {
110- ServiceDiscoveryManager discoManager = ServiceDiscoveryManager .getInstanceFor (con );
111- return discoManager .findServices (UserSearch .NAMESPACE , false , false );
152+ public static List <DomainBareJid > getSearchServices (XMPPConnection connection ) throws NoResponseException , XMPPErrorException , NotConnectedException , InterruptedException {
153+ ServiceDiscoveryManager discoManager = ServiceDiscoveryManager .getInstanceFor (connection );
154+ return discoManager .findServices (UserSearch .NAMESPACE , false , true );
112155 }
113156}
0 commit comments