move Element, Tag etc into im.conversations package

This commit is contained in:
Daniel Gultsch 2023-02-15 22:48:07 +01:00
parent eeac779e25
commit 6845380be5
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
80 changed files with 739 additions and 309 deletions

View file

@ -3,18 +3,13 @@ package eu.siacs.conversations.xml;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import eu.siacs.conversations.utils.XmlHelper;
import eu.siacs.conversations.xmpp.InvalidJid;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
import im.conversations.android.xmpp.ExtensionFactory;
import im.conversations.android.xmpp.model.Extension;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import org.jetbrains.annotations.NotNull;
@ -40,17 +35,6 @@ public class Element {
return child;
}
public <T extends Extension> T addExtension(T child) {
this.addChild(child);
return child;
}
public void addExtensions(final Collection<? extends Extension> extensions) {
for (final Extension extension : extensions) {
addExtension(extension);
}
}
public Element addChild(String name) {
this.content = null;
Element child = new Element(name);
@ -81,28 +65,6 @@ public class Element {
return null;
}
public <E extends Extension> boolean hasExtension(final Class<E> clazz) {
return Iterables.any(this.children, clazz::isInstance);
}
public <E extends Extension> E getExtension(final Class<E> clazz) {
final var extension = Iterables.find(this.children, clazz::isInstance, null);
if (extension == null) {
return null;
}
return clazz.cast(extension);
}
public <E extends Extension> Collection<E> getExtensions(final Class<E> clazz) {
return Collections2.transform(
Collections2.filter(this.children, clazz::isInstance), clazz::cast);
}
public Collection<ExtensionFactory.Id> getExtensionIds() {
return Collections2.transform(
this.children, c -> new ExtensionFactory.Id(c.getName(), c.getNamespace()));
}
public String findChildContent(String name) {
Element element = findChild(name);
return element == null ? null : element.getContent();

View file

@ -3,7 +3,6 @@ package eu.siacs.conversations.xml;
import android.util.Log;
import android.util.Xml;
import eu.siacs.conversations.Config;
import im.conversations.android.xmpp.ExtensionFactory;
import im.conversations.android.xmpp.model.Extension;
import java.io.Closeable;
import java.io.IOException;
@ -106,7 +105,7 @@ public class XmlReader implements Closeable {
final var attributes = currentTag.getAttributes();
final var namespace = attributes.get("xmlns");
final var name = currentTag.getName();
final Element element = ExtensionFactory.create(name, namespace);
final Element element = new Element(name, namespace);
element.setAttributes(currentTag.getAttributes());
Tag nextTag = this.readTag();
if (nextTag == null) {

View file

@ -1,8 +1,6 @@
package eu.siacs.conversations.xmpp.stanzas;
import im.conversations.android.xmpp.model.capabilties.EntityCapabilities;
public class PresencePacket extends AbstractAcknowledgeableStanza implements EntityCapabilities {
public class PresencePacket extends AbstractAcknowledgeableStanza {
public PresencePacket() {
super("presence");

View file

@ -1,8 +1,8 @@
package im.conversations.android.transformer;
import android.content.Context;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.manager.DiscoManager;
import im.conversations.android.xmpp.model.occupant.OccupantId;

View file

@ -0,0 +1,255 @@
package im.conversations.android.xml;
import androidx.annotation.NonNull;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import eu.siacs.conversations.xmpp.InvalidJid;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xmpp.ExtensionFactory;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.stanza.Message;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
public class Element {
private final String name;
private Hashtable<String, String> attributes = new Hashtable<>();
private String content;
protected List<Element> children = new ArrayList<>();
public Element(String name) {
this.name = name;
}
public Element(String name, String xmlns) {
this.name = name;
this.setAttribute("xmlns", xmlns);
}
public Element addChild(Element child) {
this.content = null;
children.add(child);
return child;
}
public <T extends Extension> T addExtension(T child) {
this.addChild(child);
return child;
}
public void addExtensions(final Collection<? extends Extension> extensions) {
for (final Extension extension : extensions) {
addExtension(extension);
}
}
public Element addChild(String name) {
this.content = null;
Element child = new Element(name);
children.add(child);
return child;
}
public Element addChild(String name, String xmlns) {
this.content = null;
Element child = new Element(name);
child.setAttribute("xmlns", xmlns);
children.add(child);
return child;
}
public Element setContent(String content) {
this.content = content;
this.children.clear();
return this;
}
public Element findChild(String name) {
for (Element child : this.children) {
if (child.getName().equals(name)) {
return child;
}
}
return null;
}
public <E extends Extension> boolean hasExtension(final Class<E> clazz) {
return Iterables.any(this.children, clazz::isInstance);
}
public <E extends Extension> E getExtension(final Class<E> clazz) {
final var extension = Iterables.find(this.children, clazz::isInstance, null);
if (extension == null) {
return null;
}
return clazz.cast(extension);
}
public <E extends Extension> Collection<E> getExtensions(final Class<E> clazz) {
return Collections2.transform(
Collections2.filter(this.children, clazz::isInstance), clazz::cast);
}
public Collection<ExtensionFactory.Id> getExtensionIds() {
return Collections2.transform(
this.children, c -> new ExtensionFactory.Id(c.getName(), c.getNamespace()));
}
public String findChildContent(String name) {
Element element = findChild(name);
return element == null ? null : element.getContent();
}
public Element findChild(String name, String xmlns) {
for (Element child : this.children) {
if (name.equals(child.getName()) && xmlns.equals(child.getAttribute("xmlns"))) {
return child;
}
}
return null;
}
public String findChildContent(String name, String xmlns) {
Element element = findChild(name, xmlns);
return element == null ? null : element.getContent();
}
public boolean hasChild(final String name) {
return findChild(name) != null;
}
public boolean hasChild(final String name, final String xmlns) {
return findChild(name, xmlns) != null;
}
public List<Element> getChildren() {
return this.children;
}
public Element setChildren(List<Element> children) {
this.children = children;
return this;
}
public final String getContent() {
return content;
}
public Element setAttribute(final String name, final String value) {
Preconditions.checkArgument(name != null, "The attribute must have a name");
if (value == null) {
this.attributes.remove(name);
} else {
this.attributes.put(name, value);
}
return this;
}
public Element setAttribute(final String name, final Jid value) {
return this.setAttribute(name, value == null ? null : value.toEscapedString());
}
public void removeAttribute(final String name) {
this.attributes.remove(name);
}
public Element setAttributes(Hashtable<String, String> attributes) {
this.attributes = attributes;
return this;
}
public String getAttribute(String name) {
if (this.attributes.containsKey(name)) {
return this.attributes.get(name);
} else {
return null;
}
}
public long getLongAttribute(final String name) {
final var value = Longs.tryParse(Strings.nullToEmpty(this.attributes.get(name)));
return value == null ? 0 : value;
}
public Optional<Integer> getOptionalIntAttribute(final String name) {
final String value = getAttribute(name);
if (value == null) {
return Optional.absent();
}
return Optional.fromNullable(Ints.tryParse(value));
}
public Jid getAttributeAsJid(String name) {
final String jid = this.getAttribute(name);
if (Strings.isNullOrEmpty(jid)) {
return null;
}
try {
return Jid.ofEscaped(jid);
} catch (final IllegalArgumentException e) {
return InvalidJid.of(jid, this instanceof Message);
}
}
public Hashtable<String, String> getAttributes() {
return this.attributes;
}
@NonNull
public String toString() {
final StringBuilder elementOutput = new StringBuilder();
if ((content == null) && (children.size() == 0)) {
final Tag emptyTag = Tag.empty(name);
emptyTag.setAttributes(this.attributes);
elementOutput.append(emptyTag);
} else {
final Tag startTag = Tag.start(name);
startTag.setAttributes(this.attributes);
elementOutput.append(startTag);
if (content != null) {
elementOutput.append(Entities.encode(content));
} else {
for (final Element child : children) {
elementOutput.append(child.toString());
}
}
final Tag endTag = Tag.end(name);
elementOutput.append(endTag);
}
return elementOutput.toString();
}
// TODO should ultimately be removed once everything is an extension
public final String getName() {
return name;
}
public void clearChildren() {
this.children.clear();
}
public void setAttribute(String name, long value) {
this.setAttribute(name, Long.toString(value));
}
public void setAttribute(String name, int value) {
this.setAttribute(name, Integer.toString(value));
}
public boolean getAttributeAsBoolean(String name) {
String attr = getAttribute(name);
return (attr != null && (attr.equalsIgnoreCase("true") || attr.equalsIgnoreCase("1")));
}
public String getNamespace() {
return getAttribute("xmlns");
}
}

View file

@ -0,0 +1,14 @@
package im.conversations.android.xml;
public final class Entities {
private Entities() {}
public static String encode(final String input) {
return input.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("\"", "&quot;")
.replace("'", "&apos;")
.replaceAll("[\\p{Cntrl}&&[^\n\t\r]]", "");
}
}

View file

@ -0,0 +1,103 @@
package im.conversations.android.xml;
public final class Namespace {
public static final String AVATAR_CONVERSION = "urn:xmpp:pep-vcard-conversion:0";
public static final String AVATAR_DATA = "urn:xmpp:avatar:data";
public static final String AVATAR_METADATA = "urn:xmpp:avatar:metadata";
public static final String AXOLOTL = "eu.siacs.conversations.axolotl";
public static final String AXOLOTL_BUNDLES = AXOLOTL + ".bundles";
public static final String AXOLOTL_DEVICE_LIST = AXOLOTL + ".devicelist";
public static final String BIND = "urn:ietf:params:xml:ns:xmpp-bind";
public static final String BIND2 = "urn:xmpp:bind:0";
public static final String BLOCKING = "urn:xmpp:blocking";
public static final String BOOKMARKS = "storage:bookmarks";
public static final String BOOKMARKS2 = "urn:xmpp:bookmarks:1";
public static final String BOOKMARKS2_COMPAT = BOOKMARKS2 + "#compat";
public static final String BOOKMARKS_CONVERSION = "urn:xmpp:bookmarks-conversion:0";
public static final String BYTE_STREAMS = "http://jabber.org/protocol/bytestreams";
public static final String CAPTCHA = "urn:xmpp:captcha";
public static final String CARBONS = "urn:xmpp:carbons:2";
public static final String CHANNEL_BINDING = "urn:xmpp:sasl-cb:0";
public static final String CHAT_MARKERS = "urn:xmpp:chat-markers:0";
public static final String CHAT_STATES = "http://jabber.org/protocol/chatstates";
public static final String COMMANDS = "http://jabber.org/protocol/commands";
public static final String CONFERENCE = "jabber:x:conference";
public static final String CSI = "urn:xmpp:csi:0";
public static final String DATA = "jabber:x:data";
public static final String DELAY = "urn:xmpp:delay";
public static final String DELIVERY_RECEIPTS = "urn:xmpp:receipts";
public static final String DISCO_INFO = "http://jabber.org/protocol/disco#info";
public static final String DISCO_ITEMS = "http://jabber.org/protocol/disco#items";
public static final String EASY_ONBOARDING_INVITE = "urn:xmpp:invite#invite";
public static final String ENTITY_CAPABILITIES = "http://jabber.org/protocol/caps";
public static final String ENTITY_CAPABILITIES_2 = "urn:xmpp:caps";
public static final String EXTERNAL_SERVICE_DISCOVERY = "urn:xmpp:extdisco:2";
public static final String FAST = "urn:xmpp:fast:0";
public static final String FLEXIBLE_OFFLINE_MESSAGE_RETRIEVAL =
"http://jabber.org/protocol/offline";
public static final String FORWARD = "urn:xmpp:forward:0";
public static final String HASHES = "urn:xmpp:hashes:2";
public static final String HTTP_UPLOAD = "urn:xmpp:http:upload:0";
public static final String HTTP_UPLOAD_LEGACY = "urn:xmpp:http:upload";
public static final String IBB = "http://jabber.org/protocol/ibb";
public static final String IDLE = "urn:xmpp:idle:1";
public static final String INVITE = "urn:xmpp:invite";
public static final String JABBER_CLIENT = "jabber:client";
public static final String JINGLE = "urn:xmpp:jingle:1";
public static final String JINGLE_APPS_DTLS = "urn:xmpp:jingle:apps:dtls:0";
public static final String JINGLE_APPS_GROUPING = "urn:xmpp:jingle:apps:grouping:0";
public static final String JINGLE_APPS_RTP = "urn:xmpp:jingle:apps:rtp:1";
public static final String JINGLE_ENCRYPTED_TRANSPORT = "urn:xmpp:jingle:jet:0";
public static final String JINGLE_ENCRYPTED_TRANSPORT_OMEMO = "urn:xmpp:jingle:jet-omemo:0";
public static final String JINGLE_ERRORS = "urn:xmpp:jingle:errors:1";
public static final String JINGLE_FEATURE_AUDIO = "urn:xmpp:jingle:apps:rtp:audio";
public static final String JINGLE_FEATURE_VIDEO = "urn:xmpp:jingle:apps:rtp:video";
public static final String JINGLE_FILE_TRANSFER_3 = "urn:xmpp:jingle:apps:file-transfer:3";
public static final String JINGLE_FILE_TRANSFER_4 = "urn:xmpp:jingle:apps:file-transfer:4";
public static final String JINGLE_FILE_TRANSFER_5 = "urn:xmpp:jingle:apps:file-transfer:5";
public static final String JINGLE_MESSAGE = "urn:xmpp:jingle-message:0";
public static final String JINGLE_RTP_FEEDBACK_NEGOTIATION =
"urn:xmpp:jingle:apps:rtp:rtcp-fb:0";
public static final String JINGLE_RTP_HEADER_EXTENSIONS =
"urn:xmpp:jingle:apps:rtp:rtp-hdrext:0";
public static final String JINGLE_RTP_SOURCE_SPECIFIC_MEDIA_ATTRIBUTES =
"urn:xmpp:jingle:apps:rtp:ssma:0";
public static final String JINGLE_TRANSPORTS_IBB = "urn:xmpp:jingle:transports:ibb:1";
public static final String JINGLE_TRANSPORTS_S5B = "urn:xmpp:jingle:transports:s5b:1";
public static final String JINGLE_TRANSPORT_ICE_UDP = "urn:xmpp:jingle:transports:ice-udp:1";
public static final String LAST_MESSAGE_CORRECTION = "urn:xmpp:message-correct:0";
public static final String MESSAGE_ARCHIVE_MANAGEMENT = "urn:xmpp:mam:2";
public static final String MUC = "http://jabber.org/protocol/muc";
public static final String MUC_USER = MUC + "#user";
public static final String NICK = "http://jabber.org/protocol/nick";
public static final String OCCUPANT_ID = "urn:xmpp:occupant-id:0";
public static final String OMEMO_DTLS_SRTP_VERIFICATION =
"http://gultsch.de/xmpp/drafts/omemo/dlts-srtp-verification";
public static final String OOB = "jabber:x:oob";
public static final String PARS = "urn:xmpp:pars:0";
public static final String PING = "urn:xmpp:ping";
public static final String PUB_SUB = "http://jabber.org/protocol/pubsub";
public static final String PUB_SUB_ERRORS = PUB_SUB + "#errors";
public static final String PUB_SUB_EVENT = PUB_SUB + "#event";
public static final String PUB_SUB_OWNER = PUB_SUB + "#owner";
public static final String PUB_SUB_PERSISTENT_ITEMS = PUB_SUB + "#persistent-items";
public static final String PUB_SUB_PUBLISH_OPTIONS = PUB_SUB + "#publish-options";
public static final String PUSH = "urn:xmpp:push:0";
public static final String REACTIONS = "urn:xmpp:reactions:0";
public static final String REGISTER = "jabber:iq:register";
public static final String REGISTER_STREAM_FEATURE = "http://jabber.org/features/iq-register";
public static final String REPLY = "urn:xmpp:reply:0";
public static final String RETRACT = "urn:xmpp:message-retract:0";
public static final String ROSTER = "jabber:iq:roster";
public static final String SASL = "urn:ietf:params:xml:ns:xmpp-sasl";
public static final String SASL_2 = "urn:xmpp:sasl:2";
public static final String STANZAS = "urn:ietf:params:xml:ns:xmpp-stanzas";
public static final String STANZA_IDS = "urn:xmpp:sid:0";
public static final String STREAMS = "http://etherx.jabber.org/streams";
public static final String STREAM_MANAGEMENT = "urn:xmpp:sm:3";
public static final String SYNCHRONIZATION = "im.quicksy.synchronization:0";
public static final String TLS = "urn:ietf:params:xml:ns:xmpp-tls";
public static final String UNIFIED_PUSH = "http://gultsch.de/xmpp/drafts/unified-push";
public static final String VERSION = "jabber:iq:version";
}

View file

@ -0,0 +1,112 @@
package im.conversations.android.xml;
import eu.siacs.conversations.xmpp.Jid;
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.Set;
import org.jetbrains.annotations.NotNull;
public class Tag {
public static final int NO = -1;
public static final int START = 0;
public static final int END = 1;
public static final int EMPTY = 2;
protected int type;
protected String name;
protected Hashtable<String, String> attributes = new Hashtable<String, String>();
protected Tag(int type, String name) {
this.type = type;
this.name = name;
}
public static Tag no(String text) {
return new Tag(NO, text);
}
public static Tag start(String name) {
return new Tag(START, name);
}
public static Tag end(String name) {
return new Tag(END, name);
}
public static Tag empty(String name) {
return new Tag(EMPTY, name);
}
public String getName() {
return name;
}
public String getAttribute(final String attrName) {
return this.attributes.get(attrName);
}
public Tag setAttribute(final String attrName, final String attrValue) {
this.attributes.put(attrName, attrValue);
return this;
}
public Tag setAttribute(final String attrName, final Jid attrValue) {
if (attrValue != null) {
this.attributes.put(attrName, attrValue.toEscapedString());
}
return this;
}
public void setAttributes(final Hashtable<String, String> attributes) {
this.attributes = attributes;
}
public boolean isStart(final String needle) {
if (needle == null) {
return false;
}
return (this.type == START) && (needle.equals(this.name));
}
public boolean isStart(final String name, final String namespace) {
return isStart(name) && namespace != null && namespace.equals(this.getAttribute("xmlns"));
}
public boolean isEnd(String needle) {
if (needle == null) return false;
return (this.type == END) && (needle.equals(this.name));
}
public boolean isNo() {
return (this.type == NO);
}
@NotNull
public String toString() {
final StringBuilder tagOutput = new StringBuilder();
tagOutput.append('<');
if (type == END) {
tagOutput.append('/');
}
tagOutput.append(name);
if (type != END) {
final Set<Entry<String, String>> attributeSet = attributes.entrySet();
for (final Entry<String, String> entry : attributeSet) {
tagOutput.append(' ');
tagOutput.append(entry.getKey());
tagOutput.append("=\"");
tagOutput.append(Entities.encode(entry.getValue()));
tagOutput.append('"');
}
}
if (type == EMPTY) {
tagOutput.append('/');
}
tagOutput.append('>');
return tagOutput.toString();
}
public Hashtable<String, String> getAttributes() {
return this.attributes;
}
}

View file

@ -1,7 +1,5 @@
package im.conversations.android.xml;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Tag;
import im.conversations.android.xmpp.model.StreamElement;
import java.io.IOException;
import java.io.OutputStream;
@ -83,7 +81,7 @@ public class TagWriter {
outputStream.flush();
}
public void writeStanzaAsync(StreamElement stanza) {
public void writeStanzaAsync(final StreamElement stanza) {
if (finished) {
LOGGER.info("attempting to write stanza to finished TagWriter");
} else {

View file

@ -0,0 +1,19 @@
package im.conversations.android.xml;
import com.google.common.io.ByteSource;
import java.io.IOException;
import java.io.InputStream;
public class XmlElementReader {
public static Element read(byte[] bytes) throws IOException {
return read(ByteSource.wrap(bytes).openStream());
}
public static Element read(final InputStream inputStream) throws IOException {
try (final XmlReader xmlReader = new XmlReader()) {
xmlReader.setInputStream(inputStream);
return xmlReader.readElement(xmlReader.readTag());
}
}
}

View file

@ -0,0 +1,134 @@
package im.conversations.android.xml;
import android.util.Log;
import android.util.Xml;
import eu.siacs.conversations.Config;
import im.conversations.android.xmpp.ExtensionFactory;
import im.conversations.android.xmpp.model.Extension;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class XmlReader implements Closeable {
private final XmlPullParser parser;
private InputStream is;
public XmlReader() {
this.parser = Xml.newPullParser();
try {
this.parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
} catch (XmlPullParserException e) {
Log.d(Config.LOGTAG, "error setting namespace feature on parser");
}
}
public void setInputStream(InputStream inputStream) throws IOException {
if (inputStream == null) {
throw new IOException();
}
this.is = inputStream;
try {
parser.setInput(new InputStreamReader(this.is));
} catch (XmlPullParserException e) {
throw new IOException("error resetting parser");
}
}
public void reset() throws IOException {
if (this.is == null) {
throw new IOException();
}
try {
parser.setInput(new InputStreamReader(this.is));
} catch (XmlPullParserException e) {
throw new IOException("error resetting parser");
}
}
@Override
public void close() {
this.is = null;
}
public Tag readTag() throws IOException {
try {
while (this.is != null && parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() == XmlPullParser.START_TAG) {
Tag tag = Tag.start(parser.getName());
final String xmlns = parser.getNamespace();
for (int i = 0; i < parser.getAttributeCount(); ++i) {
final String prefix = parser.getAttributePrefix(i);
String name;
if (prefix != null && !prefix.isEmpty()) {
name = prefix + ":" + parser.getAttributeName(i);
} else {
name = parser.getAttributeName(i);
}
tag.setAttribute(name, parser.getAttributeValue(i));
}
if (xmlns != null) {
tag.setAttribute("xmlns", xmlns);
}
return tag;
} else if (parser.getEventType() == XmlPullParser.END_TAG) {
return Tag.end(parser.getName());
} else if (parser.getEventType() == XmlPullParser.TEXT) {
return Tag.no(parser.getText());
}
}
} catch (Throwable throwable) {
throw new IOException(
"xml parser mishandled "
+ throwable.getClass().getSimpleName()
+ "("
+ throwable.getMessage()
+ ")",
throwable);
}
return null;
}
public <T extends Extension> T readElement(final Tag current, Class<T> clazz)
throws IOException {
final Element element = readElement(current);
if (clazz.isInstance(element)) {
return clazz.cast(element);
}
throw new IOException(
String.format("Read unexpected {%s}%s", element.getNamespace(), element.getName()));
}
public Element readElement(Tag currentTag) throws IOException {
final var attributes = currentTag.getAttributes();
final var namespace = attributes.get("xmlns");
final var name = currentTag.getName();
final Element element = ExtensionFactory.create(name, namespace);
element.setAttributes(currentTag.getAttributes());
Tag nextTag = this.readTag();
if (nextTag == null) {
throw new IOException("interrupted mid tag");
}
if (nextTag.isNo()) {
element.setContent(nextTag.getName());
nextTag = this.readTag();
if (nextTag == null) {
throw new IOException("interrupted mid tag");
}
}
while (!nextTag.isEnd(element.getName())) {
if (!nextTag.isNo()) {
Element child = this.readElement(nextTag);
element.addChild(child);
}
nextTag = this.readTag();
if (nextTag == null) {
throw new IOException("interrupted mid tag");
}
}
return element;
}
}

View file

@ -1,7 +1,5 @@
package im.conversations.android.xmpp;
import static eu.siacs.conversations.utils.Random.SECURE_RANDOM;
import android.content.Context;
import android.os.SystemClock;
import com.google.common.base.Optional;
@ -17,6 +15,7 @@ import eu.siacs.conversations.Config;
import eu.siacs.conversations.utils.CryptoHelper;
import eu.siacs.conversations.utils.PhoneHelper;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.Conversations;
import im.conversations.android.database.ConversationsDatabase;
import im.conversations.android.database.model.Account;
import java.util.ArrayList;
@ -132,6 +131,7 @@ public class ConnectionPool {
private void onStatusChanged(final XmppConnection connection) {
final Account account = connection.getAccount();
LOGGER.info("{} is {}", account.address, connection.getStatus());
if (connection.getStatus() == ConnectionState.ONLINE || connection.getStatus().isError()) {
// TODO notify QuickConversationsService of account state change
// mQuickConversationsService.signalAccountStateChange();
@ -162,7 +162,7 @@ public class ConnectionPool {
account.address);
reconnectAccount(connection);
} else {
final int timeToReconnect = SECURE_RANDOM.nextInt(10) + 2;
final int timeToReconnect = Conversations.SECURE_RANDOM.nextInt(10) + 2;
scheduleWakeUpCall(timeToReconnect);
}
} else if (connection.getStatus() == ConnectionState.REGISTRATION_SUCCESSFUL) {

View file

@ -8,7 +8,7 @@ import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
import com.google.common.io.BaseEncoding;
import com.google.common.primitives.Bytes;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Hash;
import im.conversations.android.xmpp.model.data.Data;
import im.conversations.android.xmpp.model.data.Field;

View file

@ -2,7 +2,7 @@ package im.conversations.android.xmpp;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import eu.siacs.conversations.xml.Element;
import im.conversations.android.xml.Element;
import im.conversations.android.xmpp.model.Extension;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

View file

@ -1,10 +1,6 @@
package im.conversations.android.xmpp;
import static eu.siacs.conversations.utils.Random.SECURE_RANDOM;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.SystemClock;
import android.security.KeyChain;
@ -25,7 +21,6 @@ import com.google.common.util.concurrent.SettableFuture;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.MemorizingTrustManager;
import eu.siacs.conversations.services.NotificationService;
@ -35,25 +30,22 @@ import eu.siacs.conversations.utils.PhoneHelper;
import eu.siacs.conversations.utils.Resolver;
import eu.siacs.conversations.utils.SSLSockets;
import eu.siacs.conversations.utils.SocksSocketFactory;
import eu.siacs.conversations.utils.XmlHelper;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.LocalizedContent;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xml.Tag;
import eu.siacs.conversations.xml.XmlReader;
import eu.siacs.conversations.xmpp.InvalidJid;
import eu.siacs.conversations.xmpp.Jid;
import eu.siacs.conversations.xmpp.bind.Bind2;
import eu.siacs.conversations.xmpp.forms.Data;
import eu.siacs.conversations.xmpp.stanzas.streammgmt.EnablePacket;
import eu.siacs.conversations.xmpp.stanzas.streammgmt.ResumePacket;
import im.conversations.android.Conversations;
import im.conversations.android.IDs;
import im.conversations.android.database.ConversationsDatabase;
import im.conversations.android.database.CredentialStore;
import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.Connection;
import im.conversations.android.database.model.Credential;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xml.Tag;
import im.conversations.android.xml.TagWriter;
import im.conversations.android.xml.XmlReader;
import im.conversations.android.xmpp.manager.AbstractManager;
import im.conversations.android.xmpp.manager.CarbonsManager;
import im.conversations.android.xmpp.manager.DiscoManager;
@ -64,7 +56,6 @@ import im.conversations.android.xmpp.model.csi.Inactive;
import im.conversations.android.xmpp.model.error.Condition;
import im.conversations.android.xmpp.model.error.Error;
import im.conversations.android.xmpp.model.ping.Ping;
import im.conversations.android.xmpp.model.register.Register;
import im.conversations.android.xmpp.model.sm.Ack;
import im.conversations.android.xmpp.model.sm.Enable;
import im.conversations.android.xmpp.model.sm.Request;
@ -82,9 +73,7 @@ import im.conversations.android.xmpp.processor.PresenceProcessor;
import im.conversations.android.xmpp.sasl.ChannelBinding;
import im.conversations.android.xmpp.sasl.HashedToken;
import im.conversations.android.xmpp.sasl.SaslMechanism;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.IDN;
import java.net.InetAddress;
@ -97,8 +86,8 @@ import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
@ -542,7 +531,7 @@ public class XmppConnection implements Runnable {
sc.init(
keyManager,
new X509TrustManager[] {trustManager.getInteractive(domain)},
SECURE_RANDOM);
Conversations.SECURE_RANDOM);
return sc.getSocketFactory();
}
@ -874,11 +863,9 @@ public class XmppConnection implements Runnable {
final Tag tag = tagReader.readTag();
if (tag != null && tag.isStart("features", Namespace.STREAMS)) {
this.streamFeatures = tagReader.readElement(tag, Features.class);
Log.d(
Config.LOGTAG,
account.address
+ ": processed NOP stream features after success: "
+ XmlHelper.printElementNames(this.streamFeatures));
LOGGER.info(
"Processed NOP stream features after success {}",
this.streamFeatures.getExtensionIds());
} else {
Log.d(Config.LOGTAG, account.address + ": received " + tag);
Log.d(
@ -1244,11 +1231,9 @@ public class XmppConnection implements Runnable {
final boolean needsBinding = !isBound && loginAndBind;
if (this.quickStartInProgress) {
if (this.streamFeatures.hasChild("authentication", Namespace.SASL_2)) {
Log.d(
Config.LOGTAG,
account.address
+ ": quick start in progress. ignoring features: "
+ XmlHelper.printElementNames(this.streamFeatures));
LOGGER.info(
"Quick start in progress. ignoring features: {}",
this.streamFeatures.getExtensionIds());
if (SaslMechanism.hashedToken(this.saslMechanism)) {
return;
}
@ -1304,19 +1289,13 @@ public class XmppConnection implements Runnable {
if (this.streamFeatures.hasChild("bind", Namespace.BIND)) {
sendBindRequest();
} else {
Log.d(
Config.LOGTAG,
account.address
+ ": unable to find bind feature "
+ XmlHelper.printElementNames(this.streamFeatures));
LOGGER.info(
"Could not find bind feature. Found {}",
this.streamFeatures.getExtensionIds());
throw new StateChangingException(ConnectionState.INCOMPATIBLE_SERVER);
}
} else {
Log.d(
Config.LOGTAG,
account.address
+ ": received NOP stream features: "
+ XmlHelper.printElementNames(this.streamFeatures));
LOGGER.info("Received NOP stream features: {}", this.streamFeatures.getExtensionIds());
}
}
@ -1377,7 +1356,9 @@ public class XmppConnection implements Runnable {
hashTokenRequest =
HashedToken.Mechanism.best(fastMechanisms, SSLSockets.version(this.socket));
}
final Collection<String> bindFeatures = Bind2.features(inline);
// TODO fix me. properly parse bind2 features
final Collection<String> bindFeatures =
Collections.emptyList(); // Bind2.features(inline);
quickStartAvailable =
sm
&& bindFeatures != null
@ -1473,10 +1454,9 @@ public class XmppConnection implements Runnable {
authenticate.addChild(generateBindRequest(bind));
}
if (inlineStreamManagement && streamId != null) {
final ResumePacket resume = new ResumePacket(this.streamId, stanzasReceived);
this.mSmCatchupMessageCounter.set(0);
this.mWaitingForSmCatchup.set(true);
authenticate.addChild(resume);
authenticate.addExtension(new Resume(this.streamId, this.stanzasReceived));
}
if (hashedTokenRequest != null) {
authenticate
@ -1497,155 +1477,11 @@ public class XmppConnection implements Runnable {
bind.addChild("enable", Namespace.CARBONS);
}
if (bindFeatures.contains(Namespace.STREAM_MANAGEMENT)) {
bind.addChild(new EnablePacket());
bind.addExtension(new Enable());
}
return bind;
}
private void register() {
final Credential credential = CredentialStore.getInstance(context).get(account);
final String preAuth = credential.preAuthRegistrationToken;
if (Strings.isNullOrEmpty(preAuth) || !streamFeatures.invite()) {
sendRegistryRequest();
return;
}
final Iq preAuthRequest = new Iq(Iq.Type.SET);
preAuthRequest.addChild("preauth", Namespace.PARS).setAttribute("token", preAuth);
sendIqPacketUnbound(
preAuthRequest,
(response) -> {
if (response.getType() == Iq.Type.RESULT) {
sendRegistryRequest();
} else {
final String error = ""; // response.getErrorCondition();
Log.d(Config.LOGTAG, account.address + ": failed to pre auth. " + error);
throw new StateChangingError(ConnectionState.REGISTRATION_INVALID_TOKEN);
}
});
}
private void sendRegistryRequest() {
final Iq retrieveRegistration = new Iq(Iq.Type.GET);
retrieveRegistration.addExtension(new Register());
retrieveRegistration.setTo(account.address.getDomain());
sendIqPacketUnbound(
retrieveRegistration,
(packet) -> {
if (packet.getType() == Iq.Type.TIMEOUT) {
return;
}
if (packet.getType() == Iq.Type.ERROR) {
throw new StateChangingError(ConnectionState.REGISTRATION_FAILED);
}
final Register query = packet.getExtension(Register.class);
if (query == null) {
throw new StateChangingError(ConnectionState.REGISTRATION_FAILED);
}
if (query.hasChild("username") && (query.hasChild("password"))) {
final Credential credential =
CredentialStore.getInstance(context).get(account);
final Iq registrationRequest = new Iq(Iq.Type.SET);
final Element username =
new Element("username")
.setContent(account.address.getEscapedLocal());
final Element password =
new Element("password").setContent(credential.password);
final var register = registrationRequest.addExtension(new Register());
register.addChild(username);
register.addChild(password);
registrationRequest.setFrom(account.address);
sendIqPacketUnbound(registrationRequest, this::handleRegistrationResponse);
} else if (query.hasChild("x", Namespace.DATA)) {
final Data data = Data.parse(query.findChild("x", Namespace.DATA));
final Element blob = query.findChild("data", "urn:xmpp:bob");
final String id = packet.getId();
InputStream is;
if (blob != null) {
try {
final String base64Blob = blob.getContent();
final byte[] strBlob = Base64.decode(base64Blob, Base64.DEFAULT);
is = new ByteArrayInputStream(strBlob);
} catch (Exception e) {
is = null;
}
} else {
// TODO this too needs fixing
final boolean useTor = /*context.useTorToConnect() ||*/
account.isOnion();
try {
final String url = data.getValue("url");
final String fallbackUrl = data.getValue("captcha-fallback-url");
if (url != null) {
is = HttpConnectionManager.open(url, useTor);
} else if (fallbackUrl != null) {
is = HttpConnectionManager.open(fallbackUrl, useTor);
} else {
is = null;
}
} catch (final IOException e) {
Log.d(
Config.LOGTAG,
account.address + ": unable to fetch captcha",
e);
is = null;
}
}
if (is != null) {
Bitmap captcha = BitmapFactory.decodeStream(is);
throw new StateChangingError(ConnectionState.REGISTRATION_FAILED);
}
throw new StateChangingError(ConnectionState.REGISTRATION_FAILED);
} else if (query.hasChild("instructions")
|| query.hasChild("x", Namespace.OOB)) {
final String instructions = query.findChildContent("instructions");
final Element oob = query.findChild("x", Namespace.OOB);
final String url = oob == null ? null : oob.findChildContent("url");
if (url != null) {
setAccountCreationFailed(url);
} else if (instructions != null) {
final Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(instructions);
if (matcher.find()) {
setAccountCreationFailed(
instructions.substring(matcher.start(), matcher.end()));
}
}
throw new StateChangingError(ConnectionState.REGISTRATION_FAILED);
}
});
}
private void handleRegistrationResponse(final Iq packet) {
if (packet.getType() == Iq.Type.RESULT) {
ConversationsDatabase.getInstance(context)
.accountDao()
.setLoginAndBind(account.id, true);
Log.d(
Config.LOGTAG,
account.address + ": successfully registered new account on server");
throw new StateChangingError(ConnectionState.REGISTRATION_SUCCESSFUL);
} else {
final List<String> PASSWORD_TOO_WEAK_MSGS =
Arrays.asList("The password is too weak", "Please use a longer password.");
Element error = packet.findChild("error");
ConnectionState state = ConnectionState.REGISTRATION_FAILED;
if (error != null) {
if (error.hasChild("conflict")) {
state = ConnectionState.REGISTRATION_CONFLICT;
} else if (error.hasChild("resource-constraint")
&& "wait".equals(error.getAttribute("type"))) {
state = ConnectionState.REGISTRATION_PLEASE_WAIT;
} else if (error.hasChild("not-acceptable")
&& PASSWORD_TOO_WEAK_MSGS.contains(error.findChildContent("text"))) {
state = ConnectionState.REGISTRATION_PASSWORD_TOO_WEAK;
}
}
throw new StateChangingError(state);
}
}
private void setAccountCreationFailed(final String url) {
final HttpUrl httpUrl = url == null ? null : HttpUrl.parse(url);
if (httpUrl != null && httpUrl.isHttps()) {

View file

@ -7,9 +7,9 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.database.AxolotlDatabaseStore;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.IqErrorException;
import im.conversations.android.xmpp.NodeConfiguration;
import im.conversations.android.xmpp.XmppConnection;

View file

@ -7,9 +7,9 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.database.entity.BookmarkEntity;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.NodeConfiguration;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.model.bookmark.Conference;

View file

@ -13,8 +13,8 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import eu.siacs.conversations.BuildConfig;
import eu.siacs.conversations.R;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.Entity;
import im.conversations.android.xmpp.EntityCapabilities;
import im.conversations.android.xmpp.EntityCapabilities2;

View file

@ -6,8 +6,8 @@ import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.ExtensionFactory;
import im.conversations.android.xmpp.IqErrorException;
import im.conversations.android.xmpp.NodeConfiguration;

View file

@ -6,7 +6,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import eu.siacs.conversations.utils.Patterns;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.model.data.Data;
import im.conversations.android.xmpp.model.oob.OutOfBandData;

View file

@ -1,8 +1,8 @@
package im.conversations.android.xmpp.manager;
import android.content.Context;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.model.stanza.Message;
import im.conversations.android.xmpp.model.unique.StanzaId;

View file

@ -3,7 +3,7 @@ package im.conversations.android.xmpp.model;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import eu.siacs.conversations.xml.Element;
import im.conversations.android.xml.Element;
public interface ByteContent {

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model;
import com.google.common.base.Preconditions;
import eu.siacs.conversations.xml.Element;
import im.conversations.android.xml.Element;
import im.conversations.android.xmpp.ExtensionFactory;
public class Extension extends Element {

View file

@ -4,8 +4,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.common.base.CaseFormat;
import com.google.common.base.Strings;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
@XmlElement(namespace = Namespace.HASHES)
public class Hash extends Extension {

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.avatar;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.ByteContent;
import im.conversations.android.xmpp.model.Extension;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.avatar;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.AVATAR_METADATA)

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.avatar;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.AVATAR_METADATA)

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.AXOLOTL)
package im.conversations.android.xmpp.model.axolotl;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.BLOCKING)
package im.conversations.android.xmpp.model.blocking;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.BOOKMARKS2)
package im.conversations.android.xmpp.model.bookmark;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -4,8 +4,8 @@ import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.io.BaseEncoding;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.EntityCapabilities2;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.Hash;

View file

@ -2,8 +2,8 @@ package im.conversations.android.xmpp.model.capabilties;
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.EntityCapabilities;
import im.conversations.android.xmpp.model.Extension;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.CARBONS)
package im.conversations.android.xmpp.model.carbons;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -2,8 +2,8 @@ package im.conversations.android.xmpp.model.correction;
import androidx.annotation.NonNull;
import com.google.common.base.Strings;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.LAST_MESSAGE_CORRECTION)

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.CSI)
package im.conversations.android.xmpp.model.csi;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,8 +1,8 @@
package im.conversations.android.xmpp.model.data;
import com.google.common.collect.Collections2;
import eu.siacs.conversations.xml.Element;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Element;
import im.conversations.android.xmpp.model.Extension;
import java.util.Collection;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.DATA)
package im.conversations.android.xmpp.model.data;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,8 +1,8 @@
package im.conversations.android.xmpp.model.delay;
import com.google.common.base.Strings;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.Timestamps;
import im.conversations.android.xmpp.model.Extension;
import java.text.ParseException;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.DISCO_INFO)
package im.conversations.android.xmpp.model.disco.info;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.DISCO_ITEMS)
package im.conversations.android.xmpp.model.disco.items;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.error;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
public abstract class Condition extends Extension {

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.error;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.JABBER_CLIENT)

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.error;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.STANZAS)

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.forward;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.stanza.Message;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.JABBER_CLIENT)
package im.conversations.android.xmpp.model.jabber;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.MESSAGE_ARCHIVE_MANAGEMENT)
package im.conversations.android.xmpp.model.mam;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.CHAT_MARKERS)
package im.conversations.android.xmpp.model.markers;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.MUC_USER)
package im.conversations.android.xmpp.model.muc.user;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.nick;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.NICK)

View file

@ -1,8 +1,8 @@
package im.conversations.android.xmpp.model.occupant;
import com.google.common.base.Strings;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.OCCUPANT_ID)

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.OOB)
package im.conversations.android.xmpp.model.oob;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.pars;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.PARS)

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.ping;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.PING)

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.pubsub;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.NodeConfiguration;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.data.Data;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.PUB_SUB_ERRORS)
package im.conversations.android.xmpp.model.pubsub.error;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.PUB_SUB_EVENT)
package im.conversations.android.xmpp.model.pubsub.event;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.PUB_SUB_OWNER)
package im.conversations.android.xmpp.model.pubsub.owner;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.PUB_SUB)
package im.conversations.android.xmpp.model.pubsub;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.REACTIONS)
package im.conversations.android.xmpp.model.reactions;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.DELIVERY_RECEIPTS)
package im.conversations.android.xmpp.model.receipts;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.REGISTER)
package im.conversations.android.xmpp.model.register;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,8 +1,8 @@
package im.conversations.android.xmpp.model.reply;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(namespace = Namespace.REPLY)

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.RETRACT)
package im.conversations.android.xmpp.model.retract;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,9 +1,9 @@
package im.conversations.android.xmpp.model.roster;
import com.google.common.collect.Collections2;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Element;
import im.conversations.android.xmpp.model.Extension;
import java.util.Arrays;
import java.util.Collection;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.roster;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(name = "query", namespace = Namespace.ROSTER)

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.ROSTER)
package im.conversations.android.xmpp.model.roster;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.STREAM_MANAGEMENT)
package im.conversations.android.xmpp.model.sm;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.JABBER_CLIENT)
package im.conversations.android.xmpp.model.stanza;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.CHAT_STATES)
package im.conversations.android.xmpp.model.state;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.streams;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
import im.conversations.android.xmpp.model.capabilties.EntityCapabilities;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.STREAMS)
package im.conversations.android.xmpp.model.streams;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,5 +1,5 @@
@XmlPackage(namespace = Namespace.STANZA_IDS)
package im.conversations.android.xmpp.model.unique;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlPackage;
import im.conversations.android.xml.Namespace;

View file

@ -1,7 +1,7 @@
package im.conversations.android.xmpp.model.version;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.annotation.XmlElement;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.model.Extension;
@XmlElement(name = "query", namespace = Namespace.VERSION)

View file

@ -1,8 +1,8 @@
package im.conversations.android.xmpp.processor;
import android.content.Context;
import eu.siacs.conversations.xml.Namespace;
import eu.siacs.conversations.xmpp.Jid;
import im.conversations.android.xml.Namespace;
import im.conversations.android.xmpp.Entity;
import im.conversations.android.xmpp.XmppConnection;
import im.conversations.android.xmpp.manager.AxolotlManager;

View file

@ -10,8 +10,8 @@ import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableBiMap;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.utils.SSLSockets;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.Namespace;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

View file

@ -6,10 +6,10 @@ import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.utils.SSLSockets;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.Namespace;
import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.Credential;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.Namespace;
import java.util.Collection;
import java.util.Collections;
import javax.net.ssl.SSLSocket;

View file

@ -4,8 +4,8 @@ import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNull;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.XmlElementReader;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.XmlElementReader;
import im.conversations.android.xmpp.manager.DiscoManager;
import im.conversations.android.xmpp.model.disco.info.InfoQuery;
import java.io.IOException;

View file

@ -3,8 +3,8 @@ package im.conversations.android.xmpp;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.XmlElementReader;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.XmlElementReader;
import im.conversations.android.xmpp.model.bookmark.Conference;
import im.conversations.android.xmpp.model.pubsub.PubSub;
import im.conversations.android.xmpp.model.stanza.Iq;

View file

@ -4,8 +4,8 @@ import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.XmlElementReader;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.XmlElementReader;
import im.conversations.android.xmpp.model.delay.Delay;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

View file

@ -4,8 +4,8 @@ import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import eu.siacs.conversations.xml.Element;
import eu.siacs.conversations.xml.XmlElementReader;
import im.conversations.android.xml.Element;
import im.conversations.android.xml.XmlElementReader;
import im.conversations.android.xmpp.model.error.Condition;
import im.conversations.android.xmpp.model.error.Error;
import im.conversations.android.xmpp.model.roster.Item;