mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-25 05:22:06 +01:00
Merge branch '4.2'
This commit is contained in:
commit
f42d9137b5
17 changed files with 537 additions and 69 deletions
15
build.gradle
15
build.gradle
|
@ -13,6 +13,11 @@ buildscript {
|
||||||
classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.0.10'
|
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 plugin: 'org.kordamp.gradle.markdown'
|
||||||
|
|
||||||
apply from: 'version.gradle'
|
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
|
// There is no need to ever clirr integration test projects and the
|
||||||
// smack-repl project.
|
// smack-repl project.
|
||||||
configure(integrationTestProjects + project(':smack-repl')) {
|
configure(integrationTestProjects + project(':smack-repl')) {
|
||||||
|
|
|
@ -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. |
|
| [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. |
|
| 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. |
|
| 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 |
|
| [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. |
|
| [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). |
|
| [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). |
|
||||||
|
|
19
documentation/extensions/references.md
Normal file
19
documentation/extensions/references.md
Normal file
|
@ -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...)
|
|
@ -17,14 +17,3 @@ dependencies {
|
||||||
// Add the Android jar to the Eclipse .classpath.
|
// Add the Android jar to the Eclipse .classpath.
|
||||||
compile files(androidBootClasspath)
|
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 }
|
|
||||||
|
|
|
@ -43,13 +43,15 @@ import org.jxmpp.jid.EntityFullJid;
|
||||||
* // Most servers require you to login before performing other tasks.
|
* // Most servers require you to login before performing other tasks.
|
||||||
* con.login("jsmith", "mypass");
|
* con.login("jsmith", "mypass");
|
||||||
* // Start a new conversation with John Doe and send him a message.
|
* // Start a new conversation with John Doe and send him a message.
|
||||||
* Chat chat = ChatManager.getInstanceFor(con).createChat("jdoe@igniterealtime.org", new MessageListener() {
|
* ChatManager chatManager = ChatManager.getInstanceFor(con);
|
||||||
* public void processMessage(Chat chat, Message message) {
|
* chatManager.addIncomingListener(new IncomingChatMessageListener() {
|
||||||
|
* public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
|
||||||
* // Print out any messages we get back to standard out.
|
* // Print out any messages we get back to standard out.
|
||||||
* System.out.println("Received message: " + message);
|
* System.out.println("Received message: " + message);
|
||||||
* }
|
* }
|
||||||
* });
|
* });
|
||||||
* chat.sendMessage("Howdy!");
|
* Chat chat = chatManager.chatWith("jdoe@igniterealtime.org");
|
||||||
|
* chat.send("Howdy!");
|
||||||
* // Disconnect from the server
|
* // Disconnect from the server
|
||||||
* con.disconnect();
|
* con.disconnect();
|
||||||
* </pre>
|
* </pre>
|
||||||
|
|
|
@ -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<CharSequence> {
|
|
||||||
|
|
||||||
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<CharSequence> equalsCharSequence(CharSequence charSequence) {
|
|
||||||
return new CharsequenceEquals(charSequence);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<XMPPConnection, ReferenceManager> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<ReferenceElement> getReferencesFromStanza(Stanza stanza) {
|
||||||
|
List<ReferenceElement> references = new ArrayList<>();
|
||||||
|
List<ExtensionElement> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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<ReferenceElement> {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
@ -289,6 +289,13 @@
|
||||||
<className>org.jivesoftware.smackx.httpfileupload.provider.FileTooLargeErrorProvider</className>
|
<className>org.jivesoftware.smackx.httpfileupload.provider.FileTooLargeErrorProvider</className>
|
||||||
</extensionProvider>
|
</extensionProvider>
|
||||||
|
|
||||||
|
<!-- XEP-0372: References -->
|
||||||
|
<extensionProvider>
|
||||||
|
<elementName>reference</elementName>
|
||||||
|
<namespace>urn:xmpp:reference:0</namespace>
|
||||||
|
<className>org.jivesoftware.smackx.reference.provider.ReferenceProvider</className>
|
||||||
|
</extensionProvider>
|
||||||
|
|
||||||
<!-- XEP-0380: Explicit Message Encryption -->
|
<!-- XEP-0380: Explicit Message Encryption -->
|
||||||
<extensionProvider>
|
<extensionProvider>
|
||||||
<elementName>encryption</elementName>
|
<elementName>encryption</elementName>
|
||||||
|
|
|
@ -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 = "<reference xmlns='urn:xmpp:reference:0' " +
|
||||||
|
"begin='72' " +
|
||||||
|
"end='78' " +
|
||||||
|
"type='mention' " +
|
||||||
|
"uri='xmpp:juliet@capulet.lit' />";
|
||||||
|
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 = "<reference xmlns='urn:xmpp:reference:0' " +
|
||||||
|
"type='data' " +
|
||||||
|
"uri='xmpp:fdp.shakespeare.lit?;node=fdp/submitted/stan.isode.net/accidentreport;item=ndina872be' />";
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -80,7 +80,7 @@ import org.jxmpp.util.cache.LruCache;
|
||||||
* Represents a user's roster, which is the collection of users a person receives
|
* 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.
|
* 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: <ul>
|
* modes are supported for handling these requests: <ul>
|
||||||
* <li>{@link SubscriptionMode#accept_all accept_all} -- accept all subscription requests.</li>
|
* <li>{@link SubscriptionMode#accept_all accept_all} -- accept all subscription requests.</li>
|
||||||
* <li>{@link SubscriptionMode#reject_all reject_all} -- reject all subscription requests.</li>
|
* <li>{@link SubscriptionMode#reject_all reject_all} -- reject all subscription requests.</li>
|
||||||
|
@ -384,12 +384,14 @@ public final class Roster extends Manager {
|
||||||
private synchronized Map<Resourcepart, Presence> getOrCreatePresencesInternal(BareJid entity) {
|
private synchronized Map<Resourcepart, Presence> getOrCreatePresencesInternal(BareJid entity) {
|
||||||
Map<Resourcepart, Presence> entityPresences = getPresencesInternal(entity);
|
Map<Resourcepart, Presence> entityPresences = getPresencesInternal(entity);
|
||||||
if (entityPresences == null) {
|
if (entityPresences == null) {
|
||||||
entityPresences = new ConcurrentHashMap<>();
|
|
||||||
if (contains(entity)) {
|
if (contains(entity)) {
|
||||||
|
entityPresences = new ConcurrentHashMap<>();
|
||||||
presenceMap.put(entity, entityPresences);
|
presenceMap.put(entity, entityPresences);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nonRosterPresenceMap.put(entity, entityPresences);
|
LruCache<Resourcepart, Presence> nonRosterEntityPresences = new LruCache<>(32);
|
||||||
|
nonRosterPresenceMap.put(entity, nonRosterEntityPresences);
|
||||||
|
entityPresences = nonRosterEntityPresences;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return entityPresences;
|
return entityPresences;
|
||||||
|
@ -1509,14 +1511,13 @@ public final class Roster extends Manager {
|
||||||
case unavailable:
|
case unavailable:
|
||||||
// If no resource, this is likely an offline presence as part of
|
// If no resource, this is likely an offline presence as part of
|
||||||
// a roster presence flood. In that case, we store it.
|
// a roster presence flood. In that case, we store it.
|
||||||
|
userPresences = getOrCreatePresencesInternal(key);
|
||||||
if (from.hasNoResource()) {
|
if (from.hasNoResource()) {
|
||||||
// Get the user presence map
|
// Get the user presence map
|
||||||
userPresences = getOrCreatePresencesInternal(key);
|
|
||||||
userPresences.put(Resourcepart.EMPTY, presence);
|
userPresences.put(Resourcepart.EMPTY, presence);
|
||||||
}
|
}
|
||||||
// Otherwise, this is a normal offline presence.
|
// Otherwise, this is a normal offline presence.
|
||||||
else if (presenceMap.get(key) != null) {
|
else {
|
||||||
userPresences = presenceMap.get(key);
|
|
||||||
// Store the offline presence, as it may include extra information
|
// Store the offline presence, as it may include extra information
|
||||||
// such as the user being on vacation.
|
// such as the user being on vacation.
|
||||||
userPresences.put(fromResource, presence);
|
userPresences.put(fromResource, presence);
|
||||||
|
|
|
@ -354,7 +354,7 @@ public class Jingle extends IQ {
|
||||||
buf.append(" responder=\"").append(getResponder()).append('"');
|
buf.append(" responder=\"").append(getResponder()).append('"');
|
||||||
}
|
}
|
||||||
if (getAction() != null) {
|
if (getAction() != null) {
|
||||||
buf.append(" action=\"").append(getAction().name()).append('"');
|
buf.append(" action=\"").append(getAction().toString()).append('"');
|
||||||
}
|
}
|
||||||
if (getSid() != null) {
|
if (getSid() != null) {
|
||||||
buf.append(" sid=\"").append(getSid()).append('"');
|
buf.append(" sid=\"").append(getSid()).append('"');
|
||||||
|
|
|
@ -272,7 +272,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
/**
|
/**
|
||||||
* This listeners are invoked for every stanza that got acknowledged.
|
* This listeners are invoked for every stanza that got acknowledged.
|
||||||
* <p>
|
* <p>
|
||||||
* 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.
|
* themselves after they have been invoked.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue