Search in sources :

Example 1 with ResultSetImpl

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;
}
Also used : ResultSetImpl(org.xmpp.resultsetmanagement.ResultSetImpl) QName(org.dom4j.QName) DefaultElement(org.dom4j.tree.DefaultElement) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ)

Example 2 with ResultSetImpl

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;
}
Also used : ResultSetImpl(org.xmpp.resultsetmanagement.ResultSetImpl) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) MUCRoom(org.jivesoftware.openfire.muc.MUCRoom) DataForm(org.xmpp.forms.DataForm) FormField(org.xmpp.forms.FormField)

Example 3 with ResultSetImpl

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;
}
Also used : Group(org.jivesoftware.openfire.group.Group) User(org.jivesoftware.openfire.user.User) ResultSetImpl(org.xmpp.resultsetmanagement.ResultSetImpl) JID(org.xmpp.packet.JID) Element(org.dom4j.Element) IQ(org.xmpp.packet.IQ) HashSet(java.util.HashSet)

Aggregations

Element (org.dom4j.Element)3 IQ (org.xmpp.packet.IQ)3 ResultSetImpl (org.xmpp.resultsetmanagement.ResultSetImpl)3 HashSet (java.util.HashSet)1 QName (org.dom4j.QName)1 DefaultElement (org.dom4j.tree.DefaultElement)1 Group (org.jivesoftware.openfire.group.Group)1 MUCRoom (org.jivesoftware.openfire.muc.MUCRoom)1 User (org.jivesoftware.openfire.user.User)1 DataForm (org.xmpp.forms.DataForm)1 FormField (org.xmpp.forms.FormField)1 JID (org.xmpp.packet.JID)1