use of org.xmpp.resultsetmanagement.ResultSetImpl in project Openfire by igniterealtime.
the class IQDiscoItemsHandler method handleIQ.
@Override
public IQ handleIQ(IQ packet) {
// Create a copy of the sent pack that will be used as the reply
// we only need to add the requested items to the reply if any otherwise add
// a not found error
IQ reply = IQ.createResultIQ(packet);
// TODO Implement publishing client items
if (IQ.Type.set == packet.getType()) {
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.feature_not_implemented);
return reply;
}
// Look for a DiscoItemsProvider associated with the requested entity.
// We consider the host of the recipient JID of the packet as the entity. It's the
// DiscoItemsProvider responsibility to provide the items associated with the JID's name
// together with any possible requested node.
DiscoItemsProvider itemsProvider = getProvider(packet.getTo() == null ? packet.getFrom().getNode() : packet.getTo().getNode() != null ? packet.getTo().getNode() : packet.getTo().getDomain());
if (itemsProvider != null) {
// Get the JID's name
String name = packet.getTo() == null ? null : packet.getTo().getNode();
if (name == null || name.trim().length() == 0) {
name = null;
}
// Get the requested node
Element iq = packet.getChildElement();
String node = iq.attributeValue("node");
// Check if we have items associated with the requested name and node
Iterator<DiscoItem> itemsItr = itemsProvider.getItems(name, node, packet.getFrom());
if (itemsItr != null) {
reply.setChildElement(iq.createCopy());
Element queryElement = reply.getChildElement();
// See if the requesting entity would like to apply 'result set
// management'
final Element rsmElement = packet.getChildElement().element(QName.get("set", ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT));
// apply RSM only if the element exists, and the (total) results
// set is not empty.
final boolean applyRSM = rsmElement != null && itemsItr.hasNext();
if (applyRSM) {
if (!ResultSet.isValidRSMRequest(rsmElement)) {
reply.setError(PacketError.Condition.bad_request);
return reply;
}
// Calculate which results to include.
final List<DiscoItem> rsmResults;
final List<DiscoItem> allItems = new ArrayList<>();
while (itemsItr.hasNext()) {
allItems.add(itemsItr.next());
}
final ResultSet<DiscoItem> rs = new ResultSetImpl<>(allItems);
try {
rsmResults = rs.applyRSMDirectives(rsmElement);
} catch (NullPointerException e) {
final IQ itemNotFound = IQ.createResultIQ(packet);
itemNotFound.setError(PacketError.Condition.item_not_found);
return itemNotFound;
}
// add the applicable results to the IQ-result
for (DiscoItem item : rsmResults) {
final Element resultElement = item.getElement();
resultElement.setQName(new QName(resultElement.getName(), queryElement.getNamespace()));
queryElement.add(resultElement.createCopy());
}
// overwrite the 'set' element.
queryElement.remove(queryElement.element(QName.get("set", ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT)));
queryElement.add(rs.generateSetElementFromResults(rsmResults));
} else {
// don't apply RSM:
// Add to the reply all the items provided by the DiscoItemsProvider
Element item;
while (itemsItr.hasNext()) {
item = itemsItr.next().getElement();
item.setQName(new QName(item.getName(), queryElement.getNamespace()));
queryElement.add(item.createCopy());
}
}
} else {
// If the DiscoItemsProvider has no items for the requested name and node
// then answer a not found error
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.item_not_found);
}
} else {
// If we didn't find a DiscoItemsProvider then answer a not found error
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.item_not_found);
}
return reply;
}
use of org.xmpp.resultsetmanagement.ResultSetImpl in project Openfire by igniterealtime.
the class IQMUCSearchHandler method handleIQ.
/**
* Constructs an answer on a IQ stanza that contains a search request. The
* answer will be an IQ stanza of type 'result' or 'error'.
*
* @param iq
* The IQ stanza that is the search request.
* @return An answer to the provided request.
*/
public IQ handleIQ(IQ iq) {
final IQ reply = IQ.createResultIQ(iq);
final Element formElement = iq.getChildElement().element(QName.get("x", "jabber:x:data"));
if (formElement == null) {
reply.setChildElement(getDataElement());
return reply;
}
// parse params from request.
final DataForm df = new DataForm(formElement);
boolean name_is_exact_match = false;
String subject = null;
int numusers = -1;
int numaxusers = -1;
boolean includePasswordProtectedRooms = true;
final Set<String> names = new HashSet<>();
for (final FormField field : df.getFields()) {
if (field.getVariable().equals("name")) {
names.add(field.getFirstValue());
}
}
final FormField matchFF = df.getField("name_is_exact_match");
if (matchFF != null) {
final String b = matchFF.getFirstValue();
if (b != null) {
name_is_exact_match = b.equals("1") || b.equalsIgnoreCase("true") || b.equalsIgnoreCase("yes");
}
}
final FormField subjectFF = df.getField("subject");
if (subjectFF != null) {
subject = subjectFF.getFirstValue();
}
try {
final FormField userAmountFF = df.getField("num_users");
if (userAmountFF != null) {
String value = userAmountFF.getFirstValue();
if (value != null && !"".equals(value)) {
numusers = Integer.parseInt(value);
}
}
final FormField maxUsersFF = df.getField("num_max_users");
if (maxUsersFF != null) {
String value = maxUsersFF.getFirstValue();
if (value != null && !"".equals(value)) {
numaxusers = Integer.parseInt(value);
}
}
} catch (NumberFormatException e) {
reply.setError(PacketError.Condition.bad_request);
return reply;
}
final FormField includePasswordProtectedRoomsFF = df.getField("include_password_protected");
if (includePasswordProtectedRoomsFF != null) {
final String b = includePasswordProtectedRoomsFF.getFirstValue();
if (b != null) {
if (b.equals("0") || b.equalsIgnoreCase("false") || b.equalsIgnoreCase("no")) {
includePasswordProtectedRooms = false;
}
}
}
// search for chatrooms matching the request params.
final List<MUCRoom> mucs = new ArrayList<>();
for (MUCRoom room : mucService.getChatRooms()) {
boolean find = false;
if (names.size() > 0) {
for (final String name : names) {
if (name_is_exact_match) {
if (name.equalsIgnoreCase(room.getNaturalLanguageName())) {
find = true;
break;
}
} else {
if (room.getNaturalLanguageName().toLowerCase().indexOf(name.toLowerCase()) != -1) {
find = true;
break;
}
}
}
}
if (subject != null && room.getSubject().toLowerCase().indexOf(subject.toLowerCase()) != -1) {
find = true;
}
if (numusers > -1 && room.getParticipants().size() < numusers) {
find = false;
}
if (numaxusers > -1 && room.getMaxUsers() < numaxusers) {
find = false;
}
if (!includePasswordProtectedRooms && room.isPasswordProtected()) {
find = false;
}
if (find && canBeIncludedInResult(room)) {
mucs.add(room);
}
}
final ResultSet<MUCRoom> searchResults = new ResultSetImpl<>(sortByUserAmount(mucs));
// See if the requesting entity would like to apply 'result set
// management'
final Element set = iq.getChildElement().element(QName.get("set", ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT));
final List<MUCRoom> mucrsm;
// apply RSM only if the element exists, and the (total) results
// set is not empty.
final boolean applyRSM = set != null && !mucs.isEmpty();
if (applyRSM) {
if (!ResultSet.isValidRSMRequest(set)) {
reply.setError(Condition.bad_request);
return reply;
}
try {
mucrsm = searchResults.applyRSMDirectives(set);
} catch (NullPointerException e) {
final IQ itemNotFound = IQ.createResultIQ(iq);
itemNotFound.setError(Condition.item_not_found);
return itemNotFound;
}
} else {
// if no rsm, all found rooms are part of the result.
mucrsm = new ArrayList<>(searchResults);
}
final Element res = DocumentHelper.createElement(QName.get("query", "jabber:iq:search"));
final DataForm resultform = new DataForm(DataForm.Type.result);
boolean atLeastoneResult = false;
for (MUCRoom room : mucrsm) {
final Map<String, Object> fields = new HashMap<>();
fields.put("name", room.getNaturalLanguageName());
fields.put("subject", room.getSubject());
fields.put("num_users", room.getOccupantsCount());
fields.put("num_max_users", room.getMaxUsers());
fields.put("is_password_protected", room.isPasswordProtected());
fields.put("is_member_only", room.isMembersOnly());
fields.put("jid", room.getRole().getRoleAddress().toString());
resultform.addItemFields(fields);
atLeastoneResult = true;
}
if (atLeastoneResult) {
resultform.addReportedField("name", "Name", FormField.Type.text_single);
resultform.addReportedField("subject", "Subject", FormField.Type.text_single);
resultform.addReportedField("num_users", "Number of users", FormField.Type.text_single);
resultform.addReportedField("num_max_users", "Max number allowed of users", FormField.Type.text_single);
resultform.addReportedField("is_password_protected", "Is a password protected room.", FormField.Type.boolean_type);
resultform.addReportedField("is_member_only", "Is a member only room.", FormField.Type.boolean_type);
resultform.addReportedField("jid", "JID", FormField.Type.jid_single);
}
res.add(resultform.getElement());
if (applyRSM) {
res.add(searchResults.generateSetElementFromResults(mucrsm));
}
reply.setChildElement(res);
return reply;
}
use of org.xmpp.resultsetmanagement.ResultSetImpl in project Openfire by igniterealtime.
the class SearchPlugin method processSetPacket.
/**
* Processes an IQ stanza of type 'set', which in the context of 'Jabber Search' is a search request.
*
* @param packet
* An IQ stanza of type 'get'
* @return A result IQ stanza that contains the possbile search fields.
*/
private IQ processSetPacket(IQ packet) {
if (!packet.getType().equals(IQ.Type.set)) {
throw new IllegalArgumentException("This method only accepts 'set' typed IQ stanzas as an argument.");
}
JID fromJID = packet.getFrom();
final IQ resultIQ;
// check if the request complies to the XEP-0055 standards
if (!isValidSearchRequest(packet)) {
resultIQ = IQ.createResultIQ(packet);
resultIQ.setError(Condition.bad_request);
return resultIQ;
}
final Element incomingForm = packet.getChildElement();
final boolean isDataFormQuery = (incomingForm.element(QName.get("x", "jabber:x:data")) != null);
final Element rsmElement = incomingForm.element(QName.get("set", ResultSet.NAMESPACE_RESULT_SET_MANAGEMENT));
if (rsmElement != null) {
final Element maxElement = rsmElement.element("max");
final Element startIndexElement = rsmElement.element("index");
int startIndex = 0;
if (startIndexElement != null) {
startIndex = Integer.parseInt(startIndexElement.getTextTrim());
}
int max = -1;
if (maxElement != null) {
max = Integer.parseInt(maxElement.getTextTrim());
}
final Set<User> searchResults = performSearch(incomingForm, startIndex, max);
if (groupOnly) {
Collection<Group> groups = GroupManager.getInstance().getGroups(fromJID);
Set<User> allSearchResults = new HashSet<User>(searchResults);
searchResults.clear();
for (User user : allSearchResults) {
for (Group group : groups) {
if (group.isUser(user.getUID())) {
searchResults.add(user);
}
}
}
}
// apply RSM
final List<User> rsmResults;
final ResultSet<User> rs = new ResultSetImpl<User>(searchResults);
try {
rsmResults = rs.applyRSMDirectives(rsmElement);
} catch (NullPointerException e) {
final IQ itemNotFound = IQ.createResultIQ(packet);
itemNotFound.setError(Condition.item_not_found);
return itemNotFound;
}
if (isDataFormQuery) {
resultIQ = replyDataFormResult(rsmResults, packet);
} else {
resultIQ = replyNonDataFormResult(rsmResults, packet);
}
// add the additional 'set' element.
final Element set = rs.generateSetElementFromResults(rsmResults);
resultIQ.getChildElement().add(set);
} else {
final Set<User> searchResults = performSearch(incomingForm);
if (groupOnly) {
Collection<Group> groups = GroupManager.getInstance().getGroups(fromJID);
Set<User> allSearchResults = new HashSet<User>(searchResults);
searchResults.clear();
for (User user : allSearchResults) {
for (Group group : groups) {
if (group.isUser(user.getUID())) {
searchResults.add(user);
}
}
}
}
// don't apply RSM
if (isDataFormQuery) {
resultIQ = replyDataFormResult(searchResults, packet);
} else {
resultIQ = replyNonDataFormResult(searchResults, packet);
}
}
return resultIQ;
}
Aggregations