From fe74fc23dcf11c563e1e84f65483b975f7730815 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 11 Oct 2014 17:06:20 +0200 Subject: [PATCH] Rework smackx.address (XEP-0033: Extended Stanza Addressing) - Make MultipleAddress.Type a enum - Change the signature of the methods to use Collection instead of List - Use for-each loops instead of iterators - Switch Provider to new provider pattern (using switch-case) - Use XmlStringBuilder (extend the API by two new methods) --- .../smack/util/XmlStringBuilder.java | 11 +++ .../smackx/address/MultipleRecipientInfo.java | 10 +- .../address/MultipleRecipientManager.java | 81 +++++++--------- .../address/packet/MultipleAddresses.java | 92 +++++++++---------- .../provider/MultipleAddressesProvider.java | 23 +++-- 5 files changed, 108 insertions(+), 109 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index aed38f9cc..0400b98cc 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -98,6 +98,10 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder halfOpenElement(NamedElement namedElement) { + return halfOpenElement(namedElement.getElementName()); + } + public XmlStringBuilder openElement(String name) { halfOpenElement(name).rightAngleBracket(); return this; @@ -207,6 +211,13 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder optBooleanAttribute(String name, boolean bool) { + if (bool) { + sb.append(' ').append(name).append("='true'"); + } + return this; + } + public XmlStringBuilder xmlnsAttribute(String value) { optAttribute("xmlns", value); return this; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientInfo.java index 291b228d1..0b64bf2d0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientInfo.java @@ -42,7 +42,7 @@ public class MultipleRecipientInfo { * @return list of primary recipients of the packet. */ public List getTOAddresses() { - return extension.getAddressesOfType(MultipleAddresses.TO); + return extension.getAddressesOfType(MultipleAddresses.Type.to); } /** @@ -52,7 +52,7 @@ public class MultipleRecipientInfo { * @return list of secondary recipients of the packet. */ public List getCCAddresses() { - return extension.getAddressesOfType(MultipleAddresses.CC); + return extension.getAddressesOfType(MultipleAddresses.Type.cc); } /** @@ -65,7 +65,7 @@ public class MultipleRecipientInfo { * no specific address was provided. */ public String getReplyRoom() { - List replyRoom = extension.getAddressesOfType(MultipleAddresses.REPLY_ROOM); + List replyRoom = extension.getAddressesOfType(MultipleAddresses.Type.replyroom); return replyRoom.isEmpty() ? null : ((MultipleAddresses.Address) replyRoom.get(0)).getJid(); } @@ -77,7 +77,7 @@ public class MultipleRecipientInfo { * @return true if the received packet should not be replied. */ public boolean shouldNotReply() { - return !extension.getAddressesOfType(MultipleAddresses.NO_REPLY).isEmpty(); + return !extension.getAddressesOfType(MultipleAddresses.Type.noreply).isEmpty(); } /** @@ -89,7 +89,7 @@ public class MultipleRecipientInfo { * no specific address was provided. */ public MultipleAddresses.Address getReplyAddress() { - List replyTo = extension.getAddressesOfType(MultipleAddresses.REPLY_TO); + List replyTo = extension.getAddressesOfType(MultipleAddresses.Type.replyto); return replyTo.isEmpty() ? null : (MultipleAddresses.Address) replyTo.get(0); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java index bac9c7c16..2a2edf4a3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java @@ -30,7 +30,7 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jxmpp.util.XmppStringUtils; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Collection; import java.util.List; /** @@ -43,7 +43,7 @@ import java.util.List; public class MultipleRecipientManager { /** - * Sends the specified packet to the list of specified recipients using the + * Sends the specified packet to the collection of specified recipients using the * specified connection. If the server has support for XEP-33 then only one * packet is going to be sent to the server with the multiple recipient instructions. * However, if XEP-33 is not supported by the server then the client is going to send @@ -51,11 +51,11 @@ public class MultipleRecipientManager { * * @param connection the connection to use to send the packet. * @param packet the packet to send to the list of recipients. - * @param to the list of JIDs to include in the TO list or null if no TO + * @param to the collection of JIDs to include in the TO list or null if no TO * list exists. - * @param cc the list of JIDs to include in the CC list or null if no CC + * @param cc the collection of JIDs to include in the CC list or null if no CC * list exists. - * @param bcc the list of JIDs to include in the BCC list or null if no BCC + * @param bcc the collection of JIDs to include in the BCC list or null if no BCC * list exists. * @throws FeatureNotSupportedException if special XEP-33 features where requested, but the * server does not support them. @@ -64,22 +64,22 @@ public class MultipleRecipientManager { * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ - public static void send(XMPPConnection connection, Packet packet, List to, List cc, List bcc) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException + public static void send(XMPPConnection connection, Packet packet, Collection to, Collection cc, Collection bcc) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException { send(connection, packet, to, cc, bcc, null, null, false); } /** - * Sends the specified packet to the list of specified recipients using the specified + * Sends the specified packet to the collection of specified recipients using the specified * connection. If the server has support for XEP-33 then only one packet is going to be sent to * the server with the multiple recipient instructions. However, if XEP-33 is not supported by * the server then the client is going to send the packet to each recipient. * * @param connection the connection to use to send the packet. * @param packet the packet to send to the list of recipients. - * @param to the list of JIDs to include in the TO list or null if no TO list exists. - * @param cc the list of JIDs to include in the CC list or null if no CC list exists. - * @param bcc the list of JIDs to include in the BCC list or null if no BCC list + * @param to the collection of JIDs to include in the TO list or null if no TO list exists. + * @param cc the collection of JIDs to include in the CC list or null if no CC list exists. + * @param bcc the collection of JIDs to include in the BCC list or null if no BCC list * exists. * @param replyTo address to which all replies are requested to be sent or null * indicating that they can reply to any address. @@ -93,7 +93,7 @@ public class MultipleRecipientManager { * server does not support them. * @throws NotConnectedException */ - public static void send(XMPPConnection connection, Packet packet, List to, List cc, List bcc, + public static void send(XMPPConnection connection, Packet packet, Collection to, Collection cc, Collection bcc, String replyTo, String replyRoom, boolean noReply) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException { String serviceAddress = getMultipleRecipienServiceAddress(connection); if (serviceAddress != null) { @@ -149,15 +149,13 @@ public class MultipleRecipientManager { } else { // Send reply to multiple recipients - List to = new ArrayList(); - List cc = new ArrayList(); - for (Iterator it = info.getTOAddresses().iterator(); it.hasNext();) { - String jid = it.next().getJid(); - to.add(jid); + List to = new ArrayList(info.getTOAddresses().size()); + List cc = new ArrayList(info.getCCAddresses().size()); + for (MultipleAddresses.Address jid : info.getTOAddresses()) { + to.add(jid.getJid()); } - for (Iterator it = info.getCCAddresses().iterator(); it.hasNext();) { - String jid = it.next().getJid(); - cc.add(jid); + for (MultipleAddresses.Address jid : info.getCCAddresses()) { + cc.add(jid.getJid()); } // Add original sender as a 'to' address (if not already present) if (!to.contains(original.getFrom()) && !cc.contains(original.getFrom())) { @@ -171,16 +169,7 @@ public class MultipleRecipientManager { cc.remove(bareJID); } - String serviceAddress = getMultipleRecipienServiceAddress(connection); - if (serviceAddress != null) { - // Send packet to target users using multiple recipient service provided by the server - sendThroughService(connection, reply, to, cc, null, null, null, false, - serviceAddress); - } - else { - // Server does not support XEP-33 so try to send the packet to each recipient - sendToIndividualRecipients(connection, reply, to, cc, null); - } + send(connection, reply, to, cc, null, null, null, false); } } @@ -200,51 +189,45 @@ public class MultipleRecipientManager { } private static void sendToIndividualRecipients(XMPPConnection connection, Packet packet, - List to, List cc, List bcc) throws NotConnectedException { + Collection to, Collection cc, Collection bcc) throws NotConnectedException { if (to != null) { - for (Iterator it = to.iterator(); it.hasNext();) { - String jid = it.next(); + for (String jid : to) { packet.setTo(jid); connection.sendPacket(new PacketCopy(packet.toXML())); } } if (cc != null) { - for (Iterator it = cc.iterator(); it.hasNext();) { - String jid = it.next(); + for (String jid : cc) { packet.setTo(jid); connection.sendPacket(new PacketCopy(packet.toXML())); } } if (bcc != null) { - for (Iterator it = bcc.iterator(); it.hasNext();) { - String jid = it.next(); + for (String jid : bcc) { packet.setTo(jid); connection.sendPacket(new PacketCopy(packet.toXML())); } } } - private static void sendThroughService(XMPPConnection connection, Packet packet, List to, - List cc, List bcc, String replyTo, String replyRoom, boolean noReply, + private static void sendThroughService(XMPPConnection connection, Packet packet, Collection to, + Collection cc, Collection bcc, String replyTo, String replyRoom, boolean noReply, String serviceAddress) throws NotConnectedException { // Create multiple recipient extension MultipleAddresses multipleAddresses = new MultipleAddresses(); if (to != null) { - for (Iterator it = to.iterator(); it.hasNext();) { - String jid = it.next(); - multipleAddresses.addAddress(MultipleAddresses.TO, jid, null, null, false, null); + for (String jid : to) { + multipleAddresses.addAddress(MultipleAddresses.Type.to, jid, null, null, false, null); } } if (cc != null) { - for (Iterator it = cc.iterator(); it.hasNext();) { - String jid = it.next(); - multipleAddresses.addAddress(MultipleAddresses.CC, jid, null, null, false, null); + for (String jid : cc) { + multipleAddresses.addAddress(MultipleAddresses.Type.to, jid, null, null, false, null); } } if (bcc != null) { - for (Iterator it = bcc.iterator(); it.hasNext();) { - String jid = it.next(); - multipleAddresses.addAddress(MultipleAddresses.BCC, jid, null, null, false, null); + for (String jid : bcc) { + multipleAddresses.addAddress(MultipleAddresses.Type.bcc, jid, null, null, false, null); } } if (noReply) { @@ -253,10 +236,10 @@ public class MultipleRecipientManager { else { if (replyTo != null && replyTo.trim().length() > 0) { multipleAddresses - .addAddress(MultipleAddresses.REPLY_TO, replyTo, null, null, false, null); + .addAddress(MultipleAddresses.Type.replyto, replyTo, null, null, false, null); } if (replyRoom != null && replyRoom.trim().length() > 0) { - multipleAddresses.addAddress(MultipleAddresses.REPLY_ROOM, replyRoom, null, null, + multipleAddresses.addAddress(MultipleAddresses.Type.replyroom, replyRoom, null, null, false, null); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java index 04362d024..1a5648dcb 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/packet/MultipleAddresses.java @@ -17,10 +17,11 @@ package org.jivesoftware.smackx.address.packet; +import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.util.XmlStringBuilder; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** @@ -33,13 +34,14 @@ public class MultipleAddresses implements PacketExtension { public static final String NAMESPACE = "http://jabber.org/protocol/address"; public static final String ELEMENT = "addresses"; - public static final String BCC = "bcc"; - public static final String CC = "cc"; - public static final String NO_REPLY = "noreply"; - public static final String REPLY_ROOM = "replyroom"; - public static final String REPLY_TO = "replyto"; - public static final String TO = "to"; - + public enum Type { + bcc, + cc, + noreply, + replyroom, + replyto, + to, + } private List
addresses = new ArrayList
(); @@ -54,7 +56,7 @@ public class MultipleAddresses implements PacketExtension { * @param delivered true when the packet was already delivered to this address. * @param uri used to specify an external system address, such as a sip:, sips:, or im: URI. */ - public void addAddress(String type, String jid, String node, String desc, boolean delivered, + public void addAddress(Type type, String jid, String node, String desc, boolean delivered, String uri) { // Create a new address with the specificed configuration Address address = new Address(type); @@ -72,7 +74,7 @@ public class MultipleAddresses implements PacketExtension { */ public void setNoReply() { // Create a new address with the specificed configuration - Address address = new Address(NO_REPLY); + Address address = new Address(Type.noreply); // Add the new address to the list of multiple recipients addresses.add(address); } @@ -84,10 +86,9 @@ public class MultipleAddresses implements PacketExtension { * @param type Examples of address type are: TO, CC, BCC, etc. * @return the list of addresses that matches the specified type. */ - public List
getAddressesOfType(String type) { + public List
getAddressesOfType(Type type) { List
answer = new ArrayList
(addresses.size()); - for (Iterator
it = addresses.iterator(); it.hasNext();) { - Address address = (Address) it.next(); + for (Address address : addresses) { if (address.getType().equals(type)) { answer.add(address); } @@ -96,41 +97,44 @@ public class MultipleAddresses implements PacketExtension { return answer; } + @Override public String getElementName() { return ELEMENT; } + @Override public String getNamespace() { return NAMESPACE; } - public String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append("<").append(getElementName()); - buf.append(" xmlns=\"").append(NAMESPACE).append("\">"); + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder buf = new XmlStringBuilder(this); + buf.rightAngleBracket(); // Loop through all the addresses and append them to the string buffer - for (Iterator
i = addresses.iterator(); i.hasNext();) { - Address address = (Address) i.next(); + for (Address address : addresses) { buf.append(address.toXML()); } - buf.append(""); - return buf.toString(); + buf.closeElement(this); + return buf; } - public static class Address { + public static class Address implements NamedElement { - private String type; + public static final String ELEMENT = "address"; + + private final Type type; private String jid; private String node; private String description; private boolean delivered; private String uri; - private Address(String type) { + private Address(Type type) { this.type = type; } - public String getType() { + public Type getType() { return type; } @@ -174,32 +178,26 @@ public class MultipleAddresses implements PacketExtension { this.uri = uri; } - private String toXML() { - StringBuilder buf = new StringBuilder(); - buf.append("
0) { buf.append(" desc=\""); buf.append(description).append("\""); } - if (delivered) { - buf.append(" delivered=\"true\""); - } - if (uri != null) { - buf.append(" uri=\""); - buf.append(uri).append("\""); - } - buf.append("/>"); - return buf.toString(); + buf.optBooleanAttribute("delivered", delivered); + buf.optAttribute("uri", uri); + buf.closeEmptyElement(); + return buf; } } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/provider/MultipleAddressesProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/provider/MultipleAddressesProvider.java index 25fec9ff8..77e3d6313 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/provider/MultipleAddressesProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/provider/MultipleAddressesProvider.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smackx.address.packet.MultipleAddresses; +import org.jivesoftware.smackx.address.packet.MultipleAddresses.Type; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -35,13 +36,16 @@ public class MultipleAddressesProvider extends PacketExtensionProvider