[xdata] Safe the raw character data of form field values

This commit is contained in:
Florian Schmaus 2021-07-18 17:21:50 +02:00
parent 4643d07ef4
commit 097d245358
9 changed files with 121 additions and 31 deletions

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2015-2020 Florian Schmaus * Copyright 2015-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -82,4 +82,11 @@ public class CollectionUtil {
} }
return new HashSet<>(collection); return new HashSet<>(collection);
} }
public static <T> List<T> emptyOrSingletonListFrom(T element) {
if (element == null) {
return Collections.emptyList();
}
return Collections.singletonList(element);
}
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus * Copyright 2020-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,9 +29,12 @@ public class AbstractMultiFormField extends FormField {
private final List<String> values; private final List<String> values;
private final List<String> rawValues;
protected AbstractMultiFormField(Builder<?, ?> builder) { protected AbstractMultiFormField(Builder<?, ?> builder) {
super(builder); super(builder);
values = CollectionUtil.cloneAndSeal(builder.values); values = CollectionUtil.cloneAndSeal(builder.values);
rawValues = CollectionUtil.cloneAndSeal(builder.rawValues);
} }
@Override @Override
@ -39,11 +42,16 @@ public class AbstractMultiFormField extends FormField {
return values; return values;
} }
@Override
public final List<String> getRawValues() {
return rawValues;
}
public abstract static class Builder<F extends FormField, B extends FormField.Builder<F, B>> public abstract static class Builder<F extends AbstractMultiFormField, B extends FormField.Builder<F, B>>
extends FormField.Builder<F, B> { extends FormField.Builder<F, B> {
private List<String> values; private List<String> values;
private List<String> rawValues;
protected Builder(AbstractMultiFormField formField) { protected Builder(AbstractMultiFormField formField) {
super(formField); super(formField);
@ -57,6 +65,7 @@ public class AbstractMultiFormField extends FormField {
private void ensureValuesAreInitialized() { private void ensureValuesAreInitialized() {
if (values == null) { if (values == null) {
values = new ArrayList<>(); values = new ArrayList<>();
rawValues = new ArrayList<>();
} }
} }
@ -70,7 +79,9 @@ public class AbstractMultiFormField extends FormField {
public B addValueVerbatim(CharSequence value) { public B addValueVerbatim(CharSequence value) {
ensureValuesAreInitialized(); ensureValuesAreInitialized();
values.add(value.toString()); String valueString = value.toString();
values.add(valueString);
rawValues.add(valueString);
return getThis(); return getThis();
} }
@ -83,7 +94,7 @@ public class AbstractMultiFormField extends FormField {
ensureValuesAreInitialized(); ensureValuesAreInitialized();
for (CharSequence value : values) { for (CharSequence value : values) {
this.values.add(value.toString()); addValueVerbatim(value);
} }
return getThis(); return getThis();

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus. * Copyright 2020-2021 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -42,7 +42,8 @@ public class AbstractSingleStringValueFormField extends SingleValueFormField {
return Integer.valueOf(value); return Integer.valueOf(value);
} }
public abstract static class Builder<F extends FormField, B extends FormField.Builder<F, B>> extends FormField.Builder<F, B> { public abstract static class Builder<F extends SingleValueFormField, B extends SingleValueFormField.Builder<F, B>>
extends SingleValueFormField.Builder<F, B> {
private String value; private String value;
@ -74,18 +75,16 @@ public class AbstractSingleStringValueFormField extends SingleValueFormField {
} }
public B setValue(CharSequence value) { public B setValue(CharSequence value) {
this.value = value.toString(); this.rawValue = this.value = value.toString();
return getThis(); return getThis();
} }
public B setValue(Enum<?> value) { public B setValue(Enum<?> value) {
this.value = value.toString(); return setValue(value.toString());
return getThis();
} }
public B setValue(int value) { public B setValue(int value) {
this.value = Integer.toString(value); return setValue(Integer.toString(value));
return getThis();
} }
public B setValue(URL value) { public B setValue(URL value) {

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus. * Copyright 2020-2021 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -43,7 +43,7 @@ public class BooleanFormField extends SingleValueFormField {
return new Builder(this); return new Builder(this);
} }
public static final class Builder extends FormField.Builder<BooleanFormField, BooleanFormField.Builder> { public static final class Builder extends SingleValueFormField.Builder<BooleanFormField, BooleanFormField.Builder> {
private Boolean value; private Boolean value;
private Builder(BooleanFormField booleanFormField) { private Builder(BooleanFormField booleanFormField) {
@ -57,6 +57,7 @@ public class BooleanFormField extends SingleValueFormField {
@Override @Override
protected void resetInternal() { protected void resetInternal() {
super.resetInternal();
value = null; value = null;
} }
@ -74,11 +75,13 @@ public class BooleanFormField extends SingleValueFormField {
} }
public Builder setValue(CharSequence value) { public Builder setValue(CharSequence value) {
boolean valueBoolean = ParserUtils.parseXmlBoolean(value.toString()); rawValue = value.toString();
boolean valueBoolean = ParserUtils.parseXmlBoolean(rawValue);
return setValue(valueBoolean); return setValue(valueBoolean);
} }
public Builder setValue(boolean value) { public Builder setValue(boolean value) {
rawValue = Boolean.toString(value);
this.value = value; this.value = value;
return this; return this;
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2003-2007 Jive Software, 2019-2020 Florian Schmaus. * Copyright 2003-2007 Jive Software, 2019-2021 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -271,6 +271,8 @@ public abstract class FormField implements FullyQualifiedElement {
*/ */
public abstract List<? extends CharSequence> getValues(); public abstract List<? extends CharSequence> getValues();
public abstract List<String> getRawValues();
public boolean hasValueSet() { public boolean hasValueSet() {
List<?> values = getValues(); List<?> values = getValues();
return !values.isEmpty(); return !values.isEmpty();

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus. * Copyright 2020-2021 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,14 +23,18 @@ import java.util.List;
import org.jivesoftware.smack.util.CollectionUtil; import org.jivesoftware.smack.util.CollectionUtil;
import org.jxmpp.jid.Jid; import org.jxmpp.jid.Jid;
import org.jxmpp.jid.util.JidUtil;
public class JidMultiFormField extends FormField { public final class JidMultiFormField extends FormField {
private final List<Jid> values; private final List<Jid> values;
private final List<String> rawValues;
protected JidMultiFormField(Builder builder) { protected JidMultiFormField(Builder builder) {
super(builder); super(builder);
values = CollectionUtil.cloneAndSeal(builder.values); values = CollectionUtil.cloneAndSeal(builder.values);
rawValues = CollectionUtil.cloneAndSeal(builder.rawValues);
} }
@Override @Override
@ -38,6 +42,11 @@ public class JidMultiFormField extends FormField {
return values; return values;
} }
@Override
public List<String> getRawValues() {
return rawValues;
}
public Builder asBuilder() { public Builder asBuilder() {
return new Builder(this); return new Builder(this);
} }
@ -45,6 +54,8 @@ public class JidMultiFormField extends FormField {
public static final class Builder extends FormField.Builder<JidMultiFormField, JidMultiFormField.Builder> { public static final class Builder extends FormField.Builder<JidMultiFormField, JidMultiFormField.Builder> {
private List<Jid> values; private List<Jid> values;
private List<String> rawValues;
private Builder(JidMultiFormField jidMultiFormField) { private Builder(JidMultiFormField jidMultiFormField) {
super(jidMultiFormField); super(jidMultiFormField);
values = CollectionUtil.newListWith(jidMultiFormField.getValues()); values = CollectionUtil.newListWith(jidMultiFormField.getValues());
@ -57,18 +68,30 @@ public class JidMultiFormField extends FormField {
private void ensureValuesAreInitialized() { private void ensureValuesAreInitialized() {
if (values == null) { if (values == null) {
values = new ArrayList<>(); values = new ArrayList<>();
rawValues = new ArrayList<>();
} }
} }
@Override @Override
protected void resetInternal() { protected void resetInternal() {
values = null; values = null;
rawValues = null;
} }
public Builder addValue(Jid jid) { public Builder addValue(Jid jid) {
return addValue(jid, null);
}
public Builder addValue(Jid jid, String rawValue) {
if (rawValue == null) {
rawValue = jid.toString();
}
ensureValuesAreInitialized(); ensureValuesAreInitialized();
values.add(jid); values.add(jid);
rawValues.add(rawValue);
return this; return this;
} }
@ -76,6 +99,7 @@ public class JidMultiFormField extends FormField {
ensureValuesAreInitialized(); ensureValuesAreInitialized();
values.addAll(jids); values.addAll(jids);
rawValues.addAll(JidUtil.toStringList(jids));
return this; return this;
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus. * Copyright 2020-2021 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,7 +36,7 @@ public class JidSingleFormField extends SingleValueFormField {
return new Builder(this); return new Builder(this);
} }
public static final class Builder extends FormField.Builder<JidSingleFormField, JidSingleFormField.Builder> { public static final class Builder extends SingleValueFormField.Builder<JidSingleFormField, JidSingleFormField.Builder> {
private Jid value; private Jid value;
private Builder(JidSingleFormField jidSingleFormField) { private Builder(JidSingleFormField jidSingleFormField) {
@ -50,11 +50,21 @@ public class JidSingleFormField extends SingleValueFormField {
@Override @Override
protected void resetInternal() { protected void resetInternal() {
super.resetInternal();
value = null; value = null;
} }
public Builder setValue(Jid value) { public Builder setValue(Jid value) {
return setValue(value, null);
}
public Builder setValue(Jid value, String rawValue) {
this.value = value; this.value = value;
if (rawValue != null) {
this.rawValue = rawValue;
} else {
this.rawValue = value.toString();
}
return this; return this;
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2020 Florian Schmaus. * Copyright 2020-2021 Florian Schmaus.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,23 +19,35 @@ package org.jivesoftware.smackx.xdata;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.util.CollectionUtil;
public abstract class SingleValueFormField extends FormField { public abstract class SingleValueFormField extends FormField {
private final String rawValue;
protected SingleValueFormField(Builder<?, ?> builder) { protected SingleValueFormField(Builder<?, ?> builder) {
super(builder); super(builder);
rawValue = builder.rawValue;
} }
@Override @Override
public final List<CharSequence> getValues() { public final List<CharSequence> getValues() {
CharSequence value = getValue(); CharSequence value = getValue();
if (value == null) { return CollectionUtil.emptyOrSingletonListFrom(value);
return Collections.emptyList();
}
return Collections.singletonList(value);
} }
public abstract CharSequence getValue(); public abstract CharSequence getValue();
public final String getRawValue() {
return rawValue;
}
@Override
public final List<String> getRawValues() {
String rawValue = getRawValue();
return CollectionUtil.emptyOrSingletonListFrom(rawValue);
}
@Override @Override
protected void populateExtraXmlChildElements() { protected void populateExtraXmlChildElements() {
CharSequence value = getValue(); CharSequence value = getValue();
@ -45,4 +57,24 @@ public abstract class SingleValueFormField extends FormField {
extraXmlChildElements = Collections.singletonList(new Value(value)); extraXmlChildElements = Collections.singletonList(new Value(value));
} }
public abstract static class Builder<F extends SingleValueFormField, B extends Builder<F, B>>
extends FormField.Builder<F, B> {
protected Builder(String fieldName, Type type) {
super(fieldName, type);
}
protected Builder(FormField formField) {
super(formField);
}
protected String rawValue;
@Override
protected void resetInternal() {
rawValue = null;
};
}
} }

View File

@ -237,8 +237,9 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
case jid_multi: case jid_multi:
JidMultiFormField.Builder jidMultiBuilder = FormField.jidMultiBuilder(fieldName); JidMultiFormField.Builder jidMultiBuilder = FormField.jidMultiBuilder(fieldName);
for (FormField.Value value : values) { for (FormField.Value value : values) {
Jid jid = JidCreate.from(value.getValue()); String rawValue = value.getValue().toString();
jidMultiBuilder.addValue(jid); Jid jid = JidCreate.from(rawValue);
jidMultiBuilder.addValue(jid, rawValue);
} }
builder = jidMultiBuilder; builder = jidMultiBuilder;
break; break;
@ -246,9 +247,9 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
ensureAtMostSingleValue(type, values); ensureAtMostSingleValue(type, values);
JidSingleFormField.Builder jidSingleBuilder = FormField.jidSingleBuilder(fieldName); JidSingleFormField.Builder jidSingleBuilder = FormField.jidSingleBuilder(fieldName);
if (!values.isEmpty()) { if (!values.isEmpty()) {
CharSequence jidCharSequence = values.get(0).getValue(); String rawValue = values.get(0).getValue().toString();
Jid jid = JidCreate.from(jidCharSequence); Jid jid = JidCreate.from(rawValue);
jidSingleBuilder.setValue(jid); jidSingleBuilder.setValue(jid, rawValue);
} }
builder = jidSingleBuilder; builder = jidSingleBuilder;
break; break;
@ -322,7 +323,8 @@ public class DataFormProvider extends ExtensionElementProvider<DataForm> {
private static AbstractMultiFormField.Builder<?, ?> parseMultiKindFormField(AbstractMultiFormField.Builder<?, ?> builder, private static AbstractMultiFormField.Builder<?, ?> parseMultiKindFormField(AbstractMultiFormField.Builder<?, ?> builder,
List<FormField.Value> values) { List<FormField.Value> values) {
for (FormField.Value value : values) { for (FormField.Value value : values) {
builder.addValue(value.getValue()); String rawValue = value.getValue().toString();
builder.addValue(rawValue);
} }
return builder; return builder;
} }