Search in sources :

Example 1 with SmackParsingException

use of org.jivesoftware.smack.parsing.SmackParsingException in project Smack by igniterealtime.

the class CarbonManagerProvider method parse.

@Override
public CarbonExtension parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException, ParseException {
    Direction dir = Direction.valueOf(parser.getName());
    Forwarded<Message> fwd = null;
    boolean done = false;
    while (!done) {
        XmlPullParser.Event eventType = parser.next();
        if (eventType == XmlPullParser.Event.START_ELEMENT && parser.getName().equals("forwarded")) {
            fwd = ForwardedProvider.parseForwardedMessage(parser, xmlEnvironment);
        } else if (eventType == XmlPullParser.Event.END_ELEMENT && dir == Direction.valueOf(parser.getName()))
            done = true;
    }
    if (fwd == null) {
        throw new SmackParsingException("sent/received must contain exactly one <forwarded/> element");
    }
    return new CarbonExtension(dir, fwd);
}
Also used : Message(org.jivesoftware.smack.packet.Message) CarbonExtension(org.jivesoftware.smackx.carbons.packet.CarbonExtension) XmlPullParser(org.jivesoftware.smack.xml.XmlPullParser) Direction(org.jivesoftware.smackx.carbons.packet.CarbonExtension.Direction) SmackParsingException(org.jivesoftware.smack.parsing.SmackParsingException)

Example 2 with SmackParsingException

use of org.jivesoftware.smack.parsing.SmackParsingException in project Smack by igniterealtime.

the class DataFormProvider method parse.

@Override
public DataForm parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
    DataForm.Type dataFormType = DataForm.Type.fromString(parser.getAttributeValue("", "type"));
    DataForm.Builder dataForm = DataForm.builder(dataFormType);
    String formType = null;
    DataForm.ReportedData reportedData = null;
    outerloop: while (true) {
        XmlPullParser.Event eventType = parser.next();
        switch(eventType) {
            case START_ELEMENT:
                String name = parser.getName();
                String namespace = parser.getNamespace();
                XmlEnvironment elementXmlEnvironment = XmlEnvironment.from(parser, xmlEnvironment);
                switch(name) {
                    case "instructions":
                        dataForm.addInstruction(parser.nextText());
                        break;
                    case "title":
                        dataForm.setTitle(parser.nextText());
                        break;
                    case "field":
                        // Note that we parse this form field without any potential reportedData. We only use reportedData
                        // to lookup form field types of fields under <item/>.
                        FormField formField = parseField(parser, elementXmlEnvironment, formType);
                        TextSingleFormField hiddenFormTypeField = formField.asHiddenFormTypeFieldIfPossible();
                        if (hiddenFormTypeField != null) {
                            if (formType != null) {
                                throw new SmackParsingException("Multiple hidden form type fields");
                            }
                            formType = hiddenFormTypeField.getValue();
                        }
                        dataForm.addField(formField);
                        break;
                    case "item":
                        DataForm.Item item = parseItem(parser, elementXmlEnvironment, formType, reportedData);
                        dataForm.addItem(item);
                        break;
                    case "reported":
                        if (reportedData != null) {
                            throw new SmackParsingException("Data form with multiple <reported/> elements");
                        }
                        reportedData = parseReported(parser, elementXmlEnvironment, formType);
                        dataForm.setReportedData(reportedData);
                        break;
                    // See XEP-133 Example 32 for a corner case where the data form contains this extension.
                    case RosterPacket.ELEMENT:
                        if (namespace.equals(RosterPacket.NAMESPACE)) {
                            dataForm.addExtensionElement(RosterPacketProvider.INSTANCE.parse(parser));
                        }
                        break;
                    // See XEP-141 Data Forms Layout
                    case DataLayout.ELEMENT:
                        if (namespace.equals(DataLayout.NAMESPACE)) {
                            dataForm.addExtensionElement(DataLayoutProvider.parse(parser));
                        }
                        break;
                }
                break;
            case END_ELEMENT:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
            default:
                // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
                break;
        }
    }
    return dataForm.build();
}
Also used : TextSingleFormField(org.jivesoftware.smackx.xdata.TextSingleFormField) DataForm(org.jivesoftware.smackx.xdata.packet.DataForm) ListMultiFormField(org.jivesoftware.smackx.xdata.ListMultiFormField) AbstractSingleStringValueFormField(org.jivesoftware.smackx.xdata.AbstractSingleStringValueFormField) BooleanFormField(org.jivesoftware.smackx.xdata.BooleanFormField) FormField(org.jivesoftware.smackx.xdata.FormField) ListSingleFormField(org.jivesoftware.smackx.xdata.ListSingleFormField) JidMultiFormField(org.jivesoftware.smackx.xdata.JidMultiFormField) TextSingleFormField(org.jivesoftware.smackx.xdata.TextSingleFormField) AbstractMultiFormField(org.jivesoftware.smackx.xdata.AbstractMultiFormField) JidSingleFormField(org.jivesoftware.smackx.xdata.JidSingleFormField) XmlEnvironment(org.jivesoftware.smack.packet.XmlEnvironment) SmackParsingException(org.jivesoftware.smack.parsing.SmackParsingException)

Example 3 with SmackParsingException

use of org.jivesoftware.smack.parsing.SmackParsingException in project Smack by igniterealtime.

the class DataFormProvider method parseField.

private static FormField parseField(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType, DataForm.ReportedData reportedData) throws XmlPullParserException, IOException, SmackParsingException {
    final int initialDepth = parser.getDepth();
    final String fieldName = parser.getAttributeValue("var");
    final String label = parser.getAttributeValue("", "label");
    FormField.Type type = null;
    {
        String fieldTypeString = parser.getAttributeValue("type");
        if (fieldTypeString != null) {
            type = FormField.Type.fromString(fieldTypeString);
        }
    }
    List<FormField.Value> values = new ArrayList<>();
    List<FormField.Option> options = new ArrayList<>();
    List<FormFieldChildElement> childElements = new ArrayList<>();
    boolean required = false;
    outerloop: while (true) {
        XmlPullParser.TagEvent eventType = parser.nextTag();
        switch(eventType) {
            case START_ELEMENT:
                QName qname = parser.getQName();
                if (qname.equals(FormField.Value.QNAME)) {
                    FormField.Value value = parseValue(parser);
                    values.add(value);
                } else if (qname.equals(FormField.Option.QNAME)) {
                    FormField.Option option = parseOption(parser);
                    options.add(option);
                } else if (qname.equals(FormField.Required.QNAME)) {
                    required = true;
                } else {
                    FormFieldChildElementProvider<?> provider = FormFieldChildElementProviderManager.getFormFieldChildElementProvider(qname);
                    if (provider == null) {
                        LOGGER.warning("Unknown form field child element " + qname + " ignored");
                        continue;
                    }
                    FormFieldChildElement formFieldChildElement = provider.parse(parser, XmlEnvironment.from(parser, xmlEnvironment));
                    childElements.add(formFieldChildElement);
                }
                break;
            case END_ELEMENT:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
        }
    }
    // XEP-0004 ยง 3.4 and SMACK-902
    if (type == null && reportedData != null) {
        FormField reportedFormField = reportedData.getField(fieldName);
        if (reportedFormField != null) {
            type = reportedFormField.getType();
        }
    }
    if (type == null) {
        // The field name 'FORM_TYPE' is magic.
        if (fieldName.equals(FormField.FORM_TYPE)) {
            type = FormField.Type.hidden;
        } else {
            // If no field type was explicitly provided, then we need to lookup the
            // field's type in the registry.
            type = FormFieldRegistry.lookup(formType, fieldName);
            if (type == null) {
                LOGGER.warning("The Field '" + fieldName + "' from FORM_TYPE '" + formType + "' is not registered. Field type is unknown, assuming text-single.");
                // As per XEP-0004, text-single is the default form field type, which we use as emergency fallback here.
                type = FormField.Type.text_single;
            }
        }
    }
    FormField.Builder<?, ?> builder;
    switch(type) {
        case bool:
            builder = parseBooleanFormField(fieldName, values);
            break;
        case fixed:
            builder = parseSingleKindFormField(FormField.fixedBuilder(fieldName), values);
            break;
        case hidden:
            builder = parseSingleKindFormField(FormField.hiddenBuilder(fieldName), values);
            break;
        case jid_multi:
            JidMultiFormField.Builder jidMultiBuilder = FormField.jidMultiBuilder(fieldName);
            for (FormField.Value value : values) {
                jidMultiBuilder.addValue(value);
            }
            builder = jidMultiBuilder;
            break;
        case jid_single:
            ensureAtMostSingleValue(type, values);
            JidSingleFormField.Builder jidSingleBuilder = FormField.jidSingleBuilder(fieldName);
            if (!values.isEmpty()) {
                FormField.Value value = values.get(0);
                jidSingleBuilder.setValue(value);
            }
            builder = jidSingleBuilder;
            break;
        case list_multi:
            ListMultiFormField.Builder listMultiBuilder = FormField.listMultiBuilder(fieldName);
            addOptionsToBuilder(options, listMultiBuilder);
            builder = parseMultiKindFormField(listMultiBuilder, values);
            break;
        case list_single:
            ListSingleFormField.Builder listSingleBuilder = FormField.listSingleBuilder(fieldName);
            addOptionsToBuilder(options, listSingleBuilder);
            builder = parseSingleKindFormField(listSingleBuilder, values);
            break;
        case text_multi:
            builder = parseMultiKindFormField(FormField.textMultiBuilder(fieldName), values);
            break;
        case text_private:
            builder = parseSingleKindFormField(FormField.textPrivateBuilder(fieldName), values);
            break;
        case text_single:
            builder = parseSingleKindFormField(FormField.textSingleBuilder(fieldName), values);
            break;
        default:
            // Should never happen, as we cover all types in the switch/case.
            throw new AssertionError("Unknown type " + type);
    }
    switch(type) {
        case list_multi:
        case list_single:
            break;
        default:
            if (!options.isEmpty()) {
                throw new SmackParsingException("Form fields of type " + type + " must not have options. This one had " + options.size());
            }
            break;
    }
    if (label != null) {
        builder.setLabel(label);
    }
    builder.setRequired(required);
    builder.addFormFieldChildElements(childElements);
    return builder.build();
}
Also used : ListSingleFormField(org.jivesoftware.smackx.xdata.ListSingleFormField) ArrayList(java.util.ArrayList) ListMultiFormField(org.jivesoftware.smackx.xdata.ListMultiFormField) JidSingleFormField(org.jivesoftware.smackx.xdata.JidSingleFormField) ListMultiFormField(org.jivesoftware.smackx.xdata.ListMultiFormField) AbstractSingleStringValueFormField(org.jivesoftware.smackx.xdata.AbstractSingleStringValueFormField) BooleanFormField(org.jivesoftware.smackx.xdata.BooleanFormField) FormField(org.jivesoftware.smackx.xdata.FormField) ListSingleFormField(org.jivesoftware.smackx.xdata.ListSingleFormField) JidMultiFormField(org.jivesoftware.smackx.xdata.JidMultiFormField) TextSingleFormField(org.jivesoftware.smackx.xdata.TextSingleFormField) AbstractMultiFormField(org.jivesoftware.smackx.xdata.AbstractMultiFormField) JidSingleFormField(org.jivesoftware.smackx.xdata.JidSingleFormField) FormFieldChildElement(org.jivesoftware.smackx.xdata.FormFieldChildElement) QName(javax.xml.namespace.QName) SmackParsingException(org.jivesoftware.smack.parsing.SmackParsingException) JidMultiFormField(org.jivesoftware.smackx.xdata.JidMultiFormField)

Example 4 with SmackParsingException

use of org.jivesoftware.smack.parsing.SmackParsingException in project Smack by igniterealtime.

the class AbstractXMPPConnection method parseAndProcessStanza.

protected void parseAndProcessStanza(XmlPullParser parser) throws XmlPullParserException, IOException, InterruptedException {
    ParserUtils.assertAtStartTag(parser);
    int parserDepth = parser.getDepth();
    Stanza stanza = null;
    try {
        stanza = PacketParserUtils.parseStanza(parser, incomingStreamXmlEnvironment);
    } catch (XmlPullParserException | SmackParsingException | IOException | IllegalArgumentException e) {
        CharSequence content = PacketParserUtils.parseContentDepth(parser, parserDepth);
        UnparseableStanza message = new UnparseableStanza(content, e);
        ParsingExceptionCallback callback = getParsingExceptionCallback();
        if (callback != null) {
            callback.handleUnparsableStanza(message);
        }
    }
    ParserUtils.assertAtEndTag(parser);
    if (stanza != null) {
        processStanza(stanza);
    }
}
Also used : Stanza(org.jivesoftware.smack.packet.Stanza) ParsingExceptionCallback(org.jivesoftware.smack.parsing.ParsingExceptionCallback) XmlPullParserException(org.jivesoftware.smack.xml.XmlPullParserException) IOException(java.io.IOException) SmackParsingException(org.jivesoftware.smack.parsing.SmackParsingException)

Example 5 with SmackParsingException

use of org.jivesoftware.smack.parsing.SmackParsingException in project Smack by igniterealtime.

the class PacketParserUtils method parsePresence.

/**
 * Parses a presence packet.
 *
 * @param parser the XML parser, positioned at the start of a presence packet.
 * @param outerXmlEnvironment the outer XML environment (optional).
 * @return a Presence packet.
 * @throws IOException if an I/O error occurred.
 * @throws XmlPullParserException if an error in the XML parser occurred.
 * @throws SmackParsingException if the Smack parser (provider) encountered invalid input.
 */
public static Presence parsePresence(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
    ParserUtils.assertAtStartTag(parser);
    final int initialDepth = parser.getDepth();
    XmlEnvironment presenceXmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment);
    PresenceBuilder presence = parseCommonStanzaAttributes(stanzaId -> StanzaBuilder.buildPresence(stanzaId), parser, outerXmlEnvironment);
    Presence.Type type = Presence.Type.available;
    String typeString = parser.getAttributeValue("", "type");
    if (typeString != null && !typeString.equals("")) {
        type = Presence.Type.fromString(typeString);
    }
    presence.ofType(type);
    // Parse sub-elements
    outerloop: while (true) {
        XmlPullParser.Event eventType = parser.next();
        switch(eventType) {
            case START_ELEMENT:
                String elementName = parser.getName();
                String namespace = parser.getNamespace();
                switch(elementName) {
                    case "status":
                        presence.setStatus(parser.nextText());
                        break;
                    case "priority":
                        Byte priority = ParserUtils.getByteAttributeFromNextText(parser);
                        presence.setPriority(priority);
                        break;
                    case "show":
                        String modeText = parser.nextText();
                        if (StringUtils.isNotEmpty(modeText)) {
                            presence.setMode(Presence.Mode.fromString(modeText));
                        } else {
                            // Some implementations send presence stanzas with a
                            // '<show />' element, which is a invalid XMPP presence
                            // stanza according to RFC 6121 4.7.2.1
                            LOGGER.warning("Empty or null mode text in presence show element form " + presence + "' which is invalid according to RFC6121 4.7.2.1");
                        }
                        break;
                    case "error":
                        presence.setError(parseError(parser, presenceXmlEnvironment));
                        break;
                    default:
                        // failing completely here. See SMACK-390 for more information.
                        try {
                            XmlElement extensionElement = parseExtensionElement(elementName, namespace, parser, presenceXmlEnvironment);
                            presence.addExtension(extensionElement);
                        } catch (Exception e) {
                            LOGGER.log(Level.WARNING, "Failed to parse extension element in Presence stanza: " + presence, e);
                        }
                        break;
                }
                break;
            case END_ELEMENT:
                if (parser.getDepth() == initialDepth) {
                    break outerloop;
                }
                break;
            default:
                // Catch all for incomplete switch (MissingCasesInEnumSwitch) statement.
                break;
        }
    }
    return presence.build();
}
Also used : PresenceBuilder(org.jivesoftware.smack.packet.PresenceBuilder) Presence(org.jivesoftware.smack.packet.Presence) XmlElement(org.jivesoftware.smack.packet.XmlElement) XmlPullParserException(org.jivesoftware.smack.xml.XmlPullParserException) SmackParsingException(org.jivesoftware.smack.parsing.SmackParsingException) IOException(java.io.IOException) XmppStringprepException(org.jxmpp.stringprep.XmppStringprepException) XmlEnvironment(org.jivesoftware.smack.packet.XmlEnvironment)

Aggregations

SmackParsingException (org.jivesoftware.smack.parsing.SmackParsingException)6 IOException (java.io.IOException)3 XmlPullParserException (org.jivesoftware.smack.xml.XmlPullParserException)3 XmlEnvironment (org.jivesoftware.smack.packet.XmlEnvironment)2 XmlPullParser (org.jivesoftware.smack.xml.XmlPullParser)2 AbstractMultiFormField (org.jivesoftware.smackx.xdata.AbstractMultiFormField)2 AbstractSingleStringValueFormField (org.jivesoftware.smackx.xdata.AbstractSingleStringValueFormField)2 BooleanFormField (org.jivesoftware.smackx.xdata.BooleanFormField)2 FormField (org.jivesoftware.smackx.xdata.FormField)2 JidMultiFormField (org.jivesoftware.smackx.xdata.JidMultiFormField)2 JidSingleFormField (org.jivesoftware.smackx.xdata.JidSingleFormField)2 ListMultiFormField (org.jivesoftware.smackx.xdata.ListMultiFormField)2 ListSingleFormField (org.jivesoftware.smackx.xdata.ListSingleFormField)2 TextSingleFormField (org.jivesoftware.smackx.xdata.TextSingleFormField)2 ArrayList (java.util.ArrayList)1 QName (javax.xml.namespace.QName)1 StreamErrorException (org.jivesoftware.smack.XMPPException.StreamErrorException)1 Message (org.jivesoftware.smack.packet.Message)1 Presence (org.jivesoftware.smack.packet.Presence)1 PresenceBuilder (org.jivesoftware.smack.packet.PresenceBuilder)1