[xdata] Parse forms of any kind without field type annotations

We previously only looked in the registry for 'submit' type forms. But
also 'result' type forms may be send without field type
annotations. Same is true, but less likely, for 'form' type forms.
This commit is contained in:
Florian Schmaus 2020-07-23 14:39:52 +02:00
parent cbdde0f541
commit 103ffabc08
1 changed files with 15 additions and 18 deletions

View File

@ -86,7 +86,7 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
dataForm.setTitle(parser.nextText()); dataForm.setTitle(parser.nextText());
break; break;
case "field": case "field":
FormField formField = parseField(parser, elementXmlEnvironment, formType, dataFormType); FormField formField = parseField(parser, elementXmlEnvironment, formType);
TextSingleFormField hiddenFormTypeField = formField.asHiddenFormTypeFieldIfPossible(); TextSingleFormField hiddenFormTypeField = formField.asHiddenFormTypeFieldIfPossible();
if (hiddenFormTypeField != null) { if (hiddenFormTypeField != null) {
@ -99,11 +99,11 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
dataForm.addField(formField); dataForm.addField(formField);
break; break;
case "item": case "item":
DataForm.Item item = parseItem(parser, elementXmlEnvironment, formType, dataFormType); DataForm.Item item = parseItem(parser, elementXmlEnvironment, formType);
dataForm.addItem(item); dataForm.addItem(item);
break; break;
case "reported": case "reported":
DataForm.ReportedData reported = parseReported(parser, elementXmlEnvironment, formType, dataFormType); DataForm.ReportedData reported = parseReported(parser, elementXmlEnvironment, formType);
dataForm.setReportedData(reported); dataForm.setReportedData(reported);
break; break;
// See XEP-133 Example 32 for a corner case where the data form contains this extension. // See XEP-133 Example 32 for a corner case where the data form contains this extension.
@ -133,7 +133,7 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
return dataForm.build(); return dataForm.build();
} }
private static FormField parseField(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType, DataForm.Type dataFormType) private static FormField parseField(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType)
throws XmlPullParserException, IOException, SmackParsingException { throws XmlPullParserException, IOException, SmackParsingException {
final int initialDepth = parser.getDepth(); final int initialDepth = parser.getDepth();
@ -187,16 +187,13 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
} }
if (type == null) { if (type == null) {
if (dataFormType == DataForm.Type.submit) { // If no field type was explicitly provided, then we need to lookup the
// If the data form is of type submit, and no type was explicitly provided, then we need to lookup the // field's type in the registry.
// field's type in the registry. type = FormFieldRegistry.lookup(formType, fieldName);
type = FormFieldRegistry.lookup(formType, fieldName); if (type == null) {
if (type == null) { LOGGER.warning("The Field '" + fieldName + "' from FORM_TYPE '" + formType
throw new SmackParsingException("Field of name '" + fieldName + "' (and FORM_TYPE '" + formType + "' is not registered. Field type is unknown, assuming text-single.");
+ "') not registered"); // As per XEP-0004, text-single is the default form field type, which we use as emergency fallback here.
}
} else {
// As per XEP-0004, text-single is the default form field type.
type = FormField.Type.text_single; type = FormField.Type.text_single;
} }
} }
@ -304,7 +301,7 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
return builder; return builder;
} }
private static DataForm.Item parseItem(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType, DataForm.Type dataFormType) private static DataForm.Item parseItem(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType)
throws XmlPullParserException, IOException, SmackParsingException { throws XmlPullParserException, IOException, SmackParsingException {
final int initialDepth = parser.getDepth(); final int initialDepth = parser.getDepth();
List<FormField> fields = new ArrayList<>(); List<FormField> fields = new ArrayList<>();
@ -315,7 +312,7 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
String name = parser.getName(); String name = parser.getName();
switch (name) { switch (name) {
case "field": case "field":
FormField field = parseField(parser, XmlEnvironment.from(parser, xmlEnvironment), formType, dataFormType); FormField field = parseField(parser, XmlEnvironment.from(parser, xmlEnvironment), formType);
fields.add(field); fields.add(field);
break; break;
} }
@ -330,7 +327,7 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
return new DataForm.Item(fields); return new DataForm.Item(fields);
} }
private static DataForm.ReportedData parseReported(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType, DataForm.Type dataFormType) private static DataForm.ReportedData parseReported(XmlPullParser parser, XmlEnvironment xmlEnvironment, String formType)
throws XmlPullParserException, IOException, SmackParsingException { throws XmlPullParserException, IOException, SmackParsingException {
final int initialDepth = parser.getDepth(); final int initialDepth = parser.getDepth();
List<FormField> fields = new ArrayList<>(); List<FormField> fields = new ArrayList<>();
@ -341,7 +338,7 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
String name = parser.getName(); String name = parser.getName();
switch (name) { switch (name) {
case "field": case "field":
FormField field = parseField(parser, XmlEnvironment.from(parser, xmlEnvironment), formType, dataFormType); FormField field = parseField(parser, XmlEnvironment.from(parser, xmlEnvironment), formType);
fields.add(field); fields.add(field);
break; break;
} }