diff --git a/build.gradle b/build.gradle index f94204b6b..445d94f3d 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,11 @@ buildscript { classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.10' } } + +plugins { + id 'ru.vyarus.animalsniffer' version '1.4.3' +} + apply plugin: 'org.kordamp.gradle.markdown' apply from: 'version.gradle' @@ -417,6 +422,16 @@ subprojects { } } +configure (androidProjects) { + apply plugin: 'ru.vyarus.animalsniffer' + dependencies { + signature "net.sf.androidscents.signature:android-api-level-${smackMinAndroidSdk}:2.2_r3@signature" + } + animalsniffer { + sourceSets = [sourceSets.main] + } +} + // There is no need to ever clirr integration test projects and the // smack-repl project. configure(integrationTestProjects + project(':smack-repl')) { diff --git a/documentation/extensions/index.md b/documentation/extensions/index.md index b6d863b91..4647d436e 100644 --- a/documentation/extensions/index.md +++ b/documentation/extensions/index.md @@ -95,6 +95,7 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental | [Push Notifications](pushnotifications.md) | [XEP-0357](http://xmpp.org/extensions/xep-0357.html) | Defines a way to manage push notifications from an XMPP Server. | | Stable and Unique Stanza IDs | [XEP-0359](http://xmpp.org/extensions/xep-0359.html) | This specification describes unique and stable IDs for messages. | | HTTP File Upload | [XEP-0363](http://xmpp.org/extensions/xep-0363.html) | Protocol to request permissions to upload a file to an HTTP server and get a shareable URL. | +| References | [XEP-0372](http://xmpp.org/extensions/xep-0363.html) | Add references like mentions or external data to stanzas. | | [Spoiler Messages](spoiler.md) | [XEP-0382](http://xmpp.org/extensions/xep-0382.html) | Indicate that the body of a message should be treated as a spoiler | | [Multi-User Chat Light](muclight.md) | [XEP-xxxx](http://mongooseim.readthedocs.io/en/latest/open-extensions/xeps/xep-muc-light.html) | Multi-User Chats for mobile XMPP applications and specific enviroment. | | [OMEMO Multi End Message and Object Encryption](omemo.md) | [XEP-XXXX](https://conversations.im/omemo/xep-omemo.html) | Encrypt messages using OMEMO encryption (currently only with smack-omemo-signal -> GPLv3). | diff --git a/documentation/extensions/references.md b/documentation/extensions/references.md new file mode 100644 index 000000000..85096d99a --- /dev/null +++ b/documentation/extensions/references.md @@ -0,0 +1,19 @@ +References +========== + +[Back](index.md) + +References are a way to refer to other entities like users, other messages or external data from within a message. + +Typical use-cases are mentioning other users by name, but referencing to their BareJid, or linking to a sent file. + +## Usage + +Mention a user and link to their bare jid. +``` +Message message = new Message("Alice is a realy nice person."); +BareJid alice = JidCreate.bareFrom("alice@capulet.lit"); +ReferenceManager.addMention(message, 0, 5, alice); +``` + +TODO: Add more use cases (for example for MIX, SIMS...) \ No newline at end of file diff --git a/smack-android/build.gradle b/smack-android/build.gradle index caeaae305..f71ef735f 100644 --- a/smack-android/build.gradle +++ b/smack-android/build.gradle @@ -17,14 +17,3 @@ dependencies { // Add the Android jar to the Eclipse .classpath. compile files(androidBootClasspath) } - -configure (androidProjects) { - task compileAndroid(type: JavaCompile) { - source = compileJava.source - classpath = compileJava.classpath - destinationDir = new File(buildDir, 'android') - options.bootClasspath = androidBootClasspath - } -} - -test { dependsOn androidProjects*.compileAndroid } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index 977940aa9..090aa47a4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -43,13 +43,15 @@ import org.jxmpp.jid.EntityFullJid; * // Most servers require you to login before performing other tasks. * con.login("jsmith", "mypass"); * // Start a new conversation with John Doe and send him a message. - * Chat chat = ChatManager.getInstanceFor(con).createChat("jdoe@igniterealtime.org", new MessageListener() { - * public void processMessage(Chat chat, Message message) { + * ChatManager chatManager = ChatManager.getInstanceFor(con); + * chatManager.addIncomingListener(new IncomingChatMessageListener() { + * public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) { * // Print out any messages we get back to standard out. * System.out.println("Received message: " + message); * } * }); - * chat.sendMessage("Howdy!"); + * Chat chat = chatManager.chatWith("jdoe@igniterealtime.org"); + * chat.send("Howdy!"); * // Disconnect from the server * con.disconnect(); * diff --git a/smack-core/src/test/java/org/jivesoftware/smack/test/util/CharsequenceEquals.java b/smack-core/src/test/java/org/jivesoftware/smack/test/util/CharsequenceEquals.java deleted file mode 100644 index c9a6233ef..000000000 --- a/smack-core/src/test/java/org/jivesoftware/smack/test/util/CharsequenceEquals.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * - * Copyright © 2014 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.test.util; - -import org.hamcrest.Description; -import org.hamcrest.Factory; -import org.hamcrest.Matcher; -import org.hamcrest.TypeSafeMatcher; - -public class CharsequenceEquals extends TypeSafeMatcher { - - private final String charSequenceString; - - public CharsequenceEquals(CharSequence charSequence) { - charSequenceString = charSequence.toString(); - } - - @Override - public void describeTo(Description description) { - description.appendText("Does not match CharSequence ").appendValue(charSequenceString); - } - - @Override - protected boolean matchesSafely(CharSequence item) { - String itemString = item.toString(); - return charSequenceString.equals(itemString); - } - - @Factory - public static Matcher equalsCharSequence(CharSequence charSequence) { - return new CharsequenceEquals(charSequence); - } -} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/ReferenceManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/ReferenceManager.java new file mode 100644 index 000000000..d3bdfce12 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/ReferenceManager.java @@ -0,0 +1,62 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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.smackx.reference; + +import java.util.Map; +import java.util.WeakHashMap; + +import org.jivesoftware.smack.ConnectionCreationListener; +import org.jivesoftware.smack.Manager; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPConnectionRegistry; +import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; + +public final class ReferenceManager extends Manager { + + public static final String NAMESPACE = "urn:xmpp:reference:0"; + + private static final Map INSTANCES = new WeakHashMap<>(); + + static { + XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { + @Override + public void connectionCreated(XMPPConnection connection) { + getInstanceFor(connection); + } + }); + } + + private ReferenceManager(XMPPConnection connection) { + super(connection); + ServiceDiscoveryManager.getInstanceFor(connection).addFeature(NAMESPACE); + } + + /** + * Return a new instance of the ReferenceManager for the given connection. + * + * @param connection xmpp connection + * @return reference manager instance + */ + public static ReferenceManager getInstanceFor(XMPPConnection connection) { + ReferenceManager manager = INSTANCES.get(connection); + if (manager == null) { + manager = new ReferenceManager(connection); + INSTANCES.put(connection, manager); + } + return manager; + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/ReferenceElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/ReferenceElement.java new file mode 100644 index 000000000..f3490d175 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/ReferenceElement.java @@ -0,0 +1,193 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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.smackx.reference.element; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.reference.ReferenceManager; + +import org.jxmpp.jid.BareJid; + +public class ReferenceElement implements ExtensionElement { + + public static final String ELEMENT = "reference"; + public static final String ATTR_BEGIN = "begin"; + public static final String ATTR_END = "end"; + public static final String ATTR_TYPE = "type"; + public static final String ATTR_ANCHOR = "anchor"; + public static final String ATTR_URI = "uri"; + + public enum Type { + mention, + data + } + + private final Integer begin; + private final Integer end; + private final Type type; + private final String anchor; + private final URI uri; + + // Non-XEP-compliant, but needed for SIMS + private final ExtensionElement child; + + /** + * XEP-incompliant (v0.2) constructor. This is needed for SIMS. + * + * @param begin + * @param end + * @param type + * @param anchor + * @param uri + * @param child + */ + public ReferenceElement(Integer begin, Integer end, Type type, String anchor, URI uri, ExtensionElement child) { + if (begin != null && begin < 0) { + throw new IllegalArgumentException("Attribute 'begin' MUST NOT be smaller than 0."); + } + if (end != null && end < 0) { + throw new IllegalArgumentException("Attribute 'end' MUST NOT be smaller than 0."); + } + if (begin != null && end != null && begin >= end) { + throw new IllegalArgumentException("Attribute 'begin' MUST be smaller than attribute 'end'."); + } + Objects.requireNonNull(type); + // TODO: The uri attribute is not mandatory according to SIMS, but it is according to references. + /*if (uri == null) { + throw new NullPointerException("Attribute 'uri' MUST NOT be null."); + }*/ + this.begin = begin; + this.end = end; + this.type = type; + this.anchor = anchor; + this.uri = uri; + this.child = child; + } + + /** + * XEP-Compliant constructor. + * + * @param begin + * @param end + * @param type + * @param anchor + * @param uri + */ + public ReferenceElement(Integer begin, Integer end, Type type, String anchor, URI uri) { + this(begin, end, type, anchor, uri, null); + } + + public Integer getBegin() { + return begin; + } + + public Integer getEnd() { + return end; + } + + public Type getType() { + return type; + } + + public String getAnchor() { + return anchor; + } + + public URI getUri() { + return uri; + } + + /** + * Add a reference to another users bare jid to a stanza. + * + * @param stanza stanza. + * @param begin start index of the mention in the messages body. + * @param end end index of the mention in the messages body. + * @param jid referenced jid. + */ + public static void addMention(Stanza stanza, int begin, int end, BareJid jid) { + URI uri; + try { + uri = new URI("xmpp:" + jid.toString()); + } catch (URISyntaxException e) { + throw new AssertionError("Cannot create URI from bareJid."); + } + ReferenceElement reference = new ReferenceElement(begin, end, ReferenceElement.Type.mention, null, uri); + stanza.addExtension(reference); + } + + /** + * Return a list of all reference extensions contained in a stanza. + * If there are no reference elements, return an empty list. + * + * @param stanza stanza + * @return list of all references contained in the stanza + */ + public static List getReferencesFromStanza(Stanza stanza) { + List references = new ArrayList<>(); + List extensions = stanza.getExtensions(ReferenceElement.ELEMENT, ReferenceManager.NAMESPACE); + for (ExtensionElement e : extensions) { + references.add((ReferenceElement) e); + } + return references; + } + + /** + * Return true, if the stanza contains at least one reference extension. + * + * @param stanza stanza + * @return true if stanza contains references + */ + public static boolean containsReferences(Stanza stanza) { + return getReferencesFromStanza(stanza).size() > 0; + } + + @Override + public String getNamespace() { + return ReferenceManager.NAMESPACE; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this) + .optIntAttribute(ATTR_BEGIN, begin != null ? begin : -1) + .optIntAttribute(ATTR_END, end != null ? end : -1) + .attribute(ATTR_TYPE, type.toString()) + .optAttribute(ATTR_ANCHOR, anchor) + .optAttribute(ATTR_URI, uri != null ? uri.toString() : null); + + if (child == null) { + return xml.closeEmptyElement(); + } else { + return xml.rightAngleBracket() + .append(child.toXML()) + .closeElement(this); + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/package-info.java new file mode 100644 index 000000000..d638a8983 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/element/package-info.java @@ -0,0 +1,20 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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. + */ +/** + * Smack's API for XEP-0372: References. + */ +package org.jivesoftware.smackx.reference.element; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java new file mode 100644 index 000000000..873fbdf73 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/package-info.java @@ -0,0 +1,20 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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. + */ +/** + * Smack's API for XEP-0372: References. + */ +package org.jivesoftware.smackx.reference; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/ReferenceProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/ReferenceProvider.java new file mode 100644 index 000000000..92474a48c --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/ReferenceProvider.java @@ -0,0 +1,60 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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.smackx.reference.provider; + +import java.net.URI; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.provider.ExtensionElementProvider; +import org.jivesoftware.smack.provider.ProviderManager; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smackx.reference.element.ReferenceElement; + +import org.xmlpull.v1.XmlPullParser; + +public class ReferenceProvider extends ExtensionElementProvider { + + public static final ReferenceProvider TEST_PROVIDER = new ReferenceProvider(); + + @Override + public ReferenceElement parse(XmlPullParser parser, int initialDepth) throws Exception { + Integer begin = ParserUtils.getIntegerAttribute(parser, ReferenceElement.ATTR_BEGIN); + Integer end = ParserUtils.getIntegerAttribute(parser, ReferenceElement.ATTR_END); + String typeString = parser.getAttributeValue(null, ReferenceElement.ATTR_TYPE); + ReferenceElement.Type type = ReferenceElement.Type.valueOf(typeString); + String anchor = parser.getAttributeValue(null, ReferenceElement.ATTR_ANCHOR); + String uriString = parser.getAttributeValue(null, ReferenceElement.ATTR_URI); + URI uri = uriString != null ? new URI(uriString) : null; + ExtensionElement child = null; + outerloop: while (true) { + int eventType = parser.next(); + if (eventType == XmlPullParser.START_TAG) { + String elementName = parser.getName(); + String namespace = parser.getNamespace(); + ExtensionElementProvider provider = ProviderManager.getExtensionProvider(elementName, namespace); + if (provider != null) { + child = provider.parse(parser); + } + } + if (eventType == XmlPullParser.END_TAG) { + break outerloop; + } + } + + return new ReferenceElement(begin, end, type, anchor, uri, child); + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/package-info.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/package-info.java new file mode 100644 index 000000000..48adda67c --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/reference/provider/package-info.java @@ -0,0 +1,20 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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. + */ +/** + * Smack's API for XEP-0372: References. + */ +package org.jivesoftware.smackx.reference.provider; diff --git a/smack-experimental/src/main/resources/org.jivesoftware.smack.experimental/experimental.providers b/smack-experimental/src/main/resources/org.jivesoftware.smack.experimental/experimental.providers index 686db8ee6..a47159e88 100644 --- a/smack-experimental/src/main/resources/org.jivesoftware.smack.experimental/experimental.providers +++ b/smack-experimental/src/main/resources/org.jivesoftware.smack.experimental/experimental.providers @@ -289,6 +289,13 @@ org.jivesoftware.smackx.httpfileupload.provider.FileTooLargeErrorProvider + + + reference + urn:xmpp:reference:0 + org.jivesoftware.smackx.reference.provider.ReferenceProvider + + encryption diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/reference/ReferenceTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/reference/ReferenceTest.java new file mode 100644 index 000000000..1e1eb6158 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/reference/ReferenceTest.java @@ -0,0 +1,106 @@ +/** + * + * Copyright 2018 Paul Schaub + * + * 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.smackx.reference; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertNull; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.jivesoftware.smack.test.util.SmackTestSuite; +import org.jivesoftware.smack.test.util.TestUtils; +import org.jivesoftware.smackx.reference.element.ReferenceElement; +import org.jivesoftware.smackx.reference.provider.ReferenceProvider; + +import org.junit.Test; + +public class ReferenceTest extends SmackTestSuite { + + @Test + public void providerMentionTest() throws Exception { + String xml = ""; + URI uri = new URI("xmpp:juliet@capulet.lit"); + ReferenceElement element = new ReferenceElement(72, 78, ReferenceElement.Type.mention, null, uri); + assertXMLEqual(xml, element.toXML().toString()); + assertEquals(72, (int) element.getBegin()); + assertEquals(78, (int) element.getEnd()); + assertEquals(ReferenceElement.Type.mention, element.getType()); + assertNull(element.getAnchor()); + assertEquals(uri, element.getUri()); + + ReferenceElement parsed = ReferenceProvider.TEST_PROVIDER.parse(TestUtils.getParser(xml)); + assertXMLEqual(xml, parsed.toXML().toString()); + } + + /** + * TODO: The uri might not be following the XMPP schema. + * That shouldn't matter though. + * @throws Exception + */ + @Test + public void providerDataTest() throws Exception { + String xml = ""; + URI uri = new URI("xmpp:fdp.shakespeare.lit?;node=fdp/submitted/stan.isode.net/accidentreport;item=ndina872be"); + ReferenceElement element = new ReferenceElement(null, null, ReferenceElement.Type.data, null, uri); + assertXMLEqual(xml, element.toXML().toString()); + + assertNull(element.getBegin()); + assertNull(element.getEnd()); + assertNull(element.getAnchor()); + assertEquals(ReferenceElement.Type.data, element.getType()); + assertEquals(uri, element.getUri()); + + ReferenceElement parsed = ReferenceProvider.TEST_PROVIDER.parse(TestUtils.getParser(xml)); + assertXMLEqual(xml, parsed.toXML().toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void beginGreaterEndIllegalTest() throws URISyntaxException { + new ReferenceElement(100, 10, ReferenceElement.Type.mention, null, new URI("xmpp:test@test.test")); + } + + @Test(expected = IllegalArgumentException.class) + public void beginSmallerZeroTest() throws URISyntaxException { + new ReferenceElement(-1, 12, ReferenceElement.Type.data, null, new URI("xmpp:test@test.test")); + } + + @Test(expected = IllegalArgumentException.class) + public void endSmallerZeroTest() throws URISyntaxException { + new ReferenceElement(12, -2, ReferenceElement.Type.mention, null, new URI("xmpp:test@test.test")); + } + + @Test(expected = NullPointerException.class) + public void typeArgumentNullTest() throws URISyntaxException { + new ReferenceElement(1, 2, null, null, new URI("xmpp:test@test.test")); + } + + /* + * TODO: Later maybe remove this test in case the uri attribute becomes optional. + @Test(expected = NullPointerException.class) + public void uriArgumentNullTest() { + new ReferenceElement(1, 2, ReferenceElement.Type.mention, null, null); + } + */ +} diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 11ec1e405..06ab46cae 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -80,7 +80,7 @@ import org.jxmpp.util.cache.LruCache; * Represents a user's roster, which is the collection of users a person receives * presence updates for. Roster items are categorized into groups for easier management. * - * Others users may attempt to subscribe to this user using a subscription request. Three + * Other users may attempt to subscribe to this user using a subscription request. Three * modes are supported for handling these requests:
    *
  • {@link SubscriptionMode#accept_all accept_all} -- accept all subscription requests.
  • *
  • {@link SubscriptionMode#reject_all reject_all} -- reject all subscription requests.
  • @@ -384,12 +384,14 @@ public final class Roster extends Manager { private synchronized Map getOrCreatePresencesInternal(BareJid entity) { Map entityPresences = getPresencesInternal(entity); if (entityPresences == null) { - entityPresences = new ConcurrentHashMap<>(); if (contains(entity)) { + entityPresences = new ConcurrentHashMap<>(); presenceMap.put(entity, entityPresences); } else { - nonRosterPresenceMap.put(entity, entityPresences); + LruCache nonRosterEntityPresences = new LruCache<>(32); + nonRosterPresenceMap.put(entity, nonRosterEntityPresences); + entityPresences = nonRosterEntityPresences; } } return entityPresences; @@ -1509,14 +1511,13 @@ public final class Roster extends Manager { case unavailable: // If no resource, this is likely an offline presence as part of // a roster presence flood. In that case, we store it. + userPresences = getOrCreatePresencesInternal(key); if (from.hasNoResource()) { // Get the user presence map - userPresences = getOrCreatePresencesInternal(key); userPresences.put(Resourcepart.EMPTY, presence); } // Otherwise, this is a normal offline presence. - else if (presenceMap.get(key) != null) { - userPresences = presenceMap.get(key); + else { // Store the offline presence, as it may include extra information // such as the user being on vacation. userPresences.put(fromResource, presence); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java index 99608cd22..5efbbaa73 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java @@ -354,7 +354,7 @@ public class Jingle extends IQ { buf.append(" responder=\"").append(getResponder()).append('"'); } if (getAction() != null) { - buf.append(" action=\"").append(getAction().name()).append('"'); + buf.append(" action=\"").append(getAction().toString()).append('"'); } if (getSid() != null) { buf.append(" sid=\"").append(getSid()).append('"'); diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index f196bf9b2..b49a673ed 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -272,7 +272,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { /** * This listeners are invoked for every stanza that got acknowledged. *

    - * We use a {@link ConccurrentLinkedQueue} here in order to allow the listeners to remove + * We use a {@link ConcurrentLinkedQueue} here in order to allow the listeners to remove * themselves after they have been invoked. *

    */