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);
}
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();
}
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();
}
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);
}
}
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();
}
Aggregations