Introduce UInt(16|32) datatypes

This commit is contained in:
Florian Schmaus 2019-06-10 21:39:36 +02:00
parent c0183775fe
commit ce70308099
16 changed files with 262 additions and 49 deletions

View File

@ -0,0 +1,70 @@
/**
*
* Copyright 2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.datatypes;
public abstract class Scalar extends java.lang.Number {
/**
*
*/
private static final long serialVersionUID = 1L;
private final java.lang.Number number;
protected Scalar(java.lang.Number number) {
this.number = number;
}
public final Number number() {
return number;
}
@Override
public final int intValue() {
return number.intValue();
}
@Override
public final long longValue() {
return number.longValue();
}
@Override
public final float floatValue() {
return number.floatValue();
}
@Override
public final double doubleValue() {
return number.doubleValue();
}
@Override
public final int hashCode() {
return number.hashCode();
}
@Override
public final boolean equals(Object other) {
return number.equals(other);
}
@Override
public final String toString() {
return number.toString();
}
}

View File

@ -0,0 +1,42 @@
/**
*
* Copyright 2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.datatypes;
import org.jivesoftware.smack.util.NumberUtil;
/**
* A number representing an unsigned 16-bit integer. Can be used for values with the XML schema type "xs:unsingedShort".
*/
public final class UInt16 extends Scalar {
private static final long serialVersionUID = 1L;
private final int number;
private UInt16(int number) {
super(NumberUtil.requireUShort16(number));
this.number = number;
}
public int nativeRepresentation() {
return number;
}
public static UInt16 from(int number) {
return new UInt16(number);
}
}

View File

@ -0,0 +1,42 @@
/**
*
* Copyright 2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack.datatypes;
import org.jivesoftware.smack.util.NumberUtil;
/**
* A number representing an unsigned 32-bit integer. Can be used for values with the XML schema type "xs:unsignedInt".
*/
public final class UInt32 extends Scalar {
private static final long serialVersionUID = 1L;
private final long number;
private UInt32(long number) {
super(NumberUtil.requireUInt32(number));
this.number = number;
}
public long nativeRepresentation() {
return number;
}
public static UInt32 from(long number) {
return new UInt32(number);
}
}

View File

@ -0,0 +1,21 @@
/**
*
* Copyright 2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Custom datatypes for Integers.
*/
package org.jivesoftware.smack.datatypes;

View File

@ -35,13 +35,14 @@ public class NumberUtil {
*
* @param value
*/
public static void requireUInt32(long value) {
public static long requireUInt32(long value) {
if (value < 0) {
throw new IllegalArgumentException("unsigned 32-bit integers can't be negative");
}
if (value > ((1L << 32) - 1)) {
throw new IllegalArgumentException("unsigned 32-bit integers can't be greater then 2^32 - 1");
}
return value;
}
/**

View File

@ -25,6 +25,8 @@ import java.util.Locale;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.datatypes.UInt16;
import org.jivesoftware.smack.datatypes.UInt32;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.parsing.SmackParsingException.SmackTextParseException;
import org.jivesoftware.smack.parsing.SmackParsingException.SmackUriSyntaxParsingException;
@ -204,6 +206,14 @@ public class ParserUtils {
}
}
public static UInt16 getUInt16Attribute(XmlPullParser parser, String name) {
Integer integer = getIntegerAttribute(parser, name);
if (integer == null) {
return null;
}
return UInt16.from(integer);
}
public static int getIntegerFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException {
String intString = parser.nextText();
return Integer.valueOf(intString);
@ -226,6 +236,14 @@ public class ParserUtils {
}
}
public static UInt32 getUInt32Attribute(XmlPullParser parser, String name) {
Long l = getLongAttribute(parser, name);
if (l == null) {
return null;
}
return UInt32.from(l);
}
public static double getDoubleFromNextText(XmlPullParser parser) throws XmlPullParserException, IOException {
String doubleString = parser.nextText();
return Double.valueOf(doubleString);

View File

@ -23,9 +23,9 @@ import java.util.List;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.datatypes.UInt16;
import org.jivesoftware.smack.packet.FullyQualifiedElement;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.NumberUtil;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
@ -41,9 +41,9 @@ public class MediaElement implements FormFieldChildElement {
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
private final int height;
private final UInt16 height;
private final int width;
private final UInt16 width;
private final List<Uri> uris;
@ -53,11 +53,11 @@ public class MediaElement implements FormFieldChildElement {
this.uris = Collections.unmodifiableList(builder.uris);
}
public int getHeight() {
public UInt16 getHeight() {
return height;
}
public int getWidth() {
public UInt16 getWidth() {
return width;
}
@ -83,8 +83,8 @@ public class MediaElement implements FormFieldChildElement {
@Override
public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) {
XmlStringBuilder xml = new XmlStringBuilder(this, xmlEnvironment);
xml.optIntAttribute("height", height)
.optIntAttribute("width", width)
xml.optAttribute("height", height)
.optAttribute("width", width)
.rightAngleBracket();
xml.append(uris, xmlEnvironment);
@ -102,13 +102,17 @@ public class MediaElement implements FormFieldChildElement {
}
public static final class Builder {
private int height, width;
private UInt16 height, width;
private List<Uri> uris = new ArrayList<>();
public Builder setHeightAndWidth(int height, int width) {
this.height = NumberUtil.requireUShort16(height);
this.width = NumberUtil.requireUShort16(width);
return setHeightAndWidth(UInt16.from(height), UInt16.from(width));
}
public Builder setHeightAndWidth(UInt16 height, UInt16 width) {
this.height = height;
this.width = width;
return this;
}

View File

@ -22,6 +22,7 @@ import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.datatypes.UInt16;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.parsing.SmackParsingException.SmackUriSyntaxParsingException;
import org.jivesoftware.smack.util.ParserUtils;
@ -42,8 +43,8 @@ public class MediaElementProvider extends FormFieldChildElementProvider<MediaEle
@Override
public MediaElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws IOException, XmlPullParserException, SmackUriSyntaxParsingException {
Integer height = ParserUtils.getIntegerAttribute(parser, "height");
Integer width = ParserUtils.getIntegerAttribute(parser, "width");
UInt16 height = ParserUtils.getUInt16Attribute(parser, "height");
UInt16 width = ParserUtils.getUInt16Attribute(parser, "width");
MediaElement.Builder mediaElementBuilder = MediaElement.builder();
if (height != null && width != null) {

View File

@ -22,6 +22,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jivesoftware.smack.datatypes.UInt32;
import org.jivesoftware.smack.packet.IQ;
/**
@ -147,6 +148,10 @@ public class Privacy extends IQ {
return this.getItemLists().get(listName);
}
public PrivacyItem getItem(String listName, int order) {
return getItem(listName, UInt32.from(order));
}
/**
* Returns the privacy item in the specified order.
*
@ -154,13 +159,13 @@ public class Privacy extends IQ {
* @param order the order of the element.
* @return a List with {@link PrivacyItem}
*/
public PrivacyItem getItem(String listName, int order) {
public PrivacyItem getItem(String listName, UInt32 order) {
// CHECKSTYLE:OFF
Iterator<PrivacyItem> values = getPrivacyList(listName).iterator();
PrivacyItem itemFound = null;
while (itemFound == null && values.hasNext()) {
PrivacyItem element = values.next();
if (element.getOrder() == order) {
if (element.getOrder().equals(order)) {
itemFound = element;
}
}

View File

@ -16,7 +16,9 @@
*/
package org.jivesoftware.smackx.privacy.packet;
import org.jivesoftware.smack.util.NumberUtil;
import java.util.Objects;
import org.jivesoftware.smack.datatypes.UInt32;
/**
* A privacy item acts a rule that when matched defines if a stanza should be blocked or not.
@ -46,7 +48,7 @@ public class PrivacyItem {
/**
* order is a unsigned 32-bit integer that is unique among all items in the list.
**/
private final long order;
private final UInt32 order;
/**
* Type defines if the rule is based on JIDs, roster groups or presence subscription types.
@ -72,6 +74,10 @@ public class PrivacyItem {
/** blocks outgoing presence notifications. */
private boolean filterPresenceOut = false;
public PrivacyItem(boolean allow, long order) {
this(null, null, allow, UInt32.from(order));
}
/**
* Creates a new fall-through privacy item.
*
@ -80,10 +86,14 @@ public class PrivacyItem {
* @param allow true if this is an allow item
* @param order the order of this privacy item
*/
public PrivacyItem(boolean allow, long order) {
public PrivacyItem(boolean allow, UInt32 order) {
this(null, null, allow, order);
}
public PrivacyItem(Type type, String value, boolean allow, long order) {
this(type, value, allow, UInt32.from(order));
}
/**
* Creates a new privacy item.
*
@ -98,12 +108,11 @@ public class PrivacyItem {
* @param allow true if this is an allow item
* @param order the order of this privacy item
*/
public PrivacyItem(Type type, String value, boolean allow, long order) {
NumberUtil.requireUInt32(order);
public PrivacyItem(Type type, String value, boolean allow, UInt32 order) {
this.type = type;
this.value = value;
this.allow = allow;
this.order = order;
this.order = Objects.requireNonNull(order);
}
/**
@ -215,7 +224,7 @@ public class PrivacyItem {
*
* @return the order number.
*/
public long getOrder() {
public UInt32 getOrder() {
return order;
}

View File

@ -19,6 +19,7 @@ package org.jivesoftware.smackx.privacy.provider;
import java.io.IOException;
import java.util.ArrayList;
import org.jivesoftware.smack.datatypes.UInt32;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.ParserUtils;
@ -109,7 +110,7 @@ public class PrivacyProvider extends IQProvider<Privacy> {
// Retrieves the required attributes
String actionValue = parser.getAttributeValue("", "action");
// Set the order number, this attribute is required
long order = ParserUtils.getLongAttribute(parser, "order");
UInt32 order = ParserUtils.getUInt32Attribute(parser, "order");
// If type is not set, then it's the fall-through case
String type = parser.getAttributeValue("", "type");

View File

@ -18,8 +18,8 @@ package org.jivesoftware.smackx.xdatavalidation.packet;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.datatypes.UInt32;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.NumberUtil;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
@ -339,8 +339,12 @@ public abstract class ValidateElement implements FormFieldChildElement {
public static class ListRange implements NamedElement {
public static final String ELEMENT = "list-range";
private final Long min;
private final Long max;
private final UInt32 min;
private final UInt32 max;
public ListRange(Long min, Long max) {
this(min != null ? UInt32.from(min) : null, max != null ? UInt32.from(max) : null);
}
/**
* The 'max' attribute specifies the maximum allowable number of selected/entered values. The 'min' attribute
@ -350,13 +354,7 @@ public abstract class ValidateElement implements FormFieldChildElement {
* @param min
* @param max
*/
public ListRange(Long min, Long max) {
if (min != null) {
NumberUtil.requireUInt32(min);
}
if (max != null) {
NumberUtil.requireUInt32(max);
}
public ListRange(UInt32 min, UInt32 max) {
if (max == null && min == null) {
throw new IllegalArgumentException("Either min or max must be given");
}
@ -367,8 +365,8 @@ public abstract class ValidateElement implements FormFieldChildElement {
@Override
public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
XmlStringBuilder buf = new XmlStringBuilder(this);
buf.optLongAttribute("min", getMin());
buf.optLongAttribute("max", getMax());
buf.optAttribute("min", getMin());
buf.optAttribute("max", getMax());
buf.closeEmptyElement();
return buf;
}
@ -383,7 +381,7 @@ public abstract class ValidateElement implements FormFieldChildElement {
*
* @return a positive integer, can be null
*/
public Long getMin() {
public UInt32 getMin() {
return min;
}
@ -392,7 +390,7 @@ public abstract class ValidateElement implements FormFieldChildElement {
*
* @return a positive integer, can be null
*/
public Long getMax() {
public UInt32 getMax() {
return max;
}
@ -410,8 +408,8 @@ public abstract class ValidateElement implements FormFieldChildElement {
return;
}
Long max = listRange.getMax();
Long min = listRange.getMin();
Object max = listRange.getMax();
Object min = listRange.getMin();
if ((max != null || min != null) && formField.getType() != FormField.Type.list_multi) {
throw new ValidationConsistencyException(
"Field type is not of type 'list-multi' while a 'list-range' is defined.");

View File

@ -21,6 +21,7 @@ import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.datatypes.UInt32;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
@ -72,8 +73,8 @@ public class DataValidationProvider extends FormFieldChildElementProvider<Valida
dataValidation = new RegexValidateElement(dataType, parser.nextText());
break;
case ListRange.ELEMENT:
Long min = ParserUtils.getLongAttribute(parser, "min");
Long max = ParserUtils.getLongAttribute(parser, "max");
UInt32 min = ParserUtils.getUInt32Attribute(parser, "min");
UInt32 max = ParserUtils.getUInt32Attribute(parser, "max");
if (min != null || max != null) {
listRange = new ListRange(min, max);
} else {

View File

@ -43,8 +43,8 @@ public class MediaElementProviderTest {
"</media>";
MediaElement mediaElement = SmackTestUtil.parse(xml, MediaElementProvider.class, parserKind);
assertEquals(80, mediaElement.getHeight());
assertEquals(290, mediaElement.getWidth());
assertEquals(80, mediaElement.getHeight().intValue());
assertEquals(290, mediaElement.getWidth().intValue());
List<MediaElement.Uri> uris = mediaElement.getUris();
assertEquals(1, uris.size());

View File

@ -59,11 +59,11 @@ public class PrivacyProviderTest extends InitExtensions {
assertEquals(PrivacyItem.Type.jid, first.getType());
assertEquals("tybalt@example.com", first.getValue());
assertEquals(false, first.isAllow());
assertEquals(1, first.getOrder());
assertEquals(1L, first.getOrder().nativeRepresentation());
PrivacyItem second = pl.get(1);
assertEquals(true, second.isAllow());
assertEquals(2, second.getOrder());
assertEquals(2L, second.getOrder().nativeRepresentation());
}
@Test
@ -95,11 +95,11 @@ public class PrivacyProviderTest extends InitExtensions {
assertEquals(PrivacyItem.Type.jid, first.getType());
assertEquals("tybalt@example.com", first.getValue());
assertEquals(false, first.isAllow());
assertEquals(1, first.getOrder());
assertEquals(1L, first.getOrder().nativeRepresentation());
PrivacyItem second = pl.get(1);
assertTrue(second.isAllow());
assertEquals(2, second.getOrder());
assertEquals(2L, second.getOrder().nativeRepresentation());
assertTrue(second.isFilterMessage());
assertTrue(second.isFilterPresenceIn());
assertFalse(second.isFilterPresenceOut());

View File

@ -105,8 +105,8 @@ public class DataValidationTest extends SmackTestSuite {
assertEquals("min-val", rdv.getMin());
assertEquals("max-val", rdv.getMax());
assertNotNull(rdv.getListRange());
assertEquals(Long.valueOf(111), rdv.getListRange().getMin());
assertEquals(999, rdv.getListRange().getMax().intValue());
assertEquals(111L, rdv.getListRange().getMin().nativeRepresentation());
assertEquals(999L, rdv.getListRange().getMax().nativeRepresentation());
assertNotNull(dv.toXML());
xml = dv.toXML().toString();