diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java new file mode 100644 index 000000000..fe2bca23a --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/Scalar.java @@ -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(); + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java new file mode 100644 index 000000000..999597401 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt16.java @@ -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); + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java new file mode 100644 index 000000000..cb6c9aa28 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/UInt32.java @@ -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); + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/datatypes/package-info.java b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/package-info.java new file mode 100644 index 000000000..15c7fd36f --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/datatypes/package-info.java @@ -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; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java index 9f5040f52..140fff4e3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/NumberUtil.java @@ -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; } /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java index e69d65b3c..feeba45ab 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java @@ -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); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/element/MediaElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/element/MediaElement.java index 2447d1494..b831933e5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/element/MediaElement.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/element/MediaElement.java @@ -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 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 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; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/provider/MediaElementProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/provider/MediaElementProvider.java index e5f33b2a2..c4b8616b5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/provider/MediaElementProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/mediaelement/provider/MediaElementProvider.java @@ -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 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; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java index 0ad6c91a4..c977fdaf3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/PrivacyItem.java @@ -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; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/provider/PrivacyProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/provider/PrivacyProvider.java index 28d6f957e..792fdd299 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/provider/PrivacyProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/provider/PrivacyProvider.java @@ -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 { // 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"); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/packet/ValidateElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/packet/ValidateElement.java index 2cdb49bc5..cf2be2b09 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/packet/ValidateElement.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/packet/ValidateElement.java @@ -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."); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationProvider.java index 416151b3f..3a9d18189 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationProvider.java @@ -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"; 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 uris = mediaElement.getUris(); assertEquals(1, uris.size()); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/privacy/provider/PrivacyProviderTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/privacy/provider/PrivacyProviderTest.java index 829e0a4f4..3a8ede436 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/privacy/provider/PrivacyProviderTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/privacy/provider/PrivacyProviderTest.java @@ -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()); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationTest.java index 7fac92c8e..522a72f08 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/xdatavalidation/provider/DataValidationTest.java @@ -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();