001/** 002 * 003 * Copyright 2003-2006 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.jivesoftware.smackx.address.packet; 019 020import java.util.ArrayList; 021import java.util.List; 022 023import org.jivesoftware.smack.packet.ExtensionElement; 024import org.jivesoftware.smack.packet.NamedElement; 025import org.jivesoftware.smack.util.XmlStringBuilder; 026 027import org.jxmpp.jid.Jid; 028 029/** 030 * Stanza extension that contains the list of addresses that a stanza should be sent or was sent. 031 * 032 * @author Gaston Dombiak 033 */ 034public class MultipleAddresses implements ExtensionElement { 035 036 public static final String NAMESPACE = "http://jabber.org/protocol/address"; 037 public static final String ELEMENT = "addresses"; 038 039 public enum Type { 040 bcc, 041 cc, 042 noreply, 043 replyroom, 044 replyto, 045 to, 046 047 /** 048 * The "original from" type used to indicate the real originator of the stanza. 049 * <p> 050 * This Extended Stanza Addressing type is not specified in XEP-33, but in XEP-45 ยง 7.2.14 (Example 36). 051 * </p> 052 */ 053 ofrom, 054 } 055 056 private final List<Address> addresses = new ArrayList<>(); 057 058 /** 059 * Adds a new address to which the stanza is going to be sent or was sent. 060 * 061 * @param type on of the static type (BCC, CC, NO_REPLY, REPLY_ROOM, etc.) 062 * @param jid the JID address of the recipient. 063 * @param node used to specify a sub-addressable unit at a particular JID, corresponding to 064 * a Service Discovery node. 065 * @param desc used to specify human-readable information for this address. 066 * @param delivered true when the stanza was already delivered to this address. 067 * @param uri used to specify an external system address, such as a sip:, sips:, or im: URI. 068 */ 069 public void addAddress(Type type, Jid jid, String node, String desc, boolean delivered, 070 String uri) { 071 // Create a new address with the specified configuration 072 Address address = new Address(type); 073 address.setJid(jid); 074 address.setNode(node); 075 address.setDescription(desc); 076 address.setDelivered(delivered); 077 address.setUri(uri); 078 // Add the new address to the list of multiple recipients 079 addresses.add(address); 080 } 081 082 /** 083 * Indicate that the stanza being sent should not be replied. 084 */ 085 public void setNoReply() { 086 // Create a new address with the specified configuration 087 Address address = new Address(Type.noreply); 088 // Add the new address to the list of multiple recipients 089 addresses.add(address); 090 } 091 092 /** 093 * Returns the list of addresses that matches the specified type. Examples of address 094 * type are: TO, CC, BCC, etc.. 095 * 096 * @param type Examples of address type are: TO, CC, BCC, etc. 097 * @return the list of addresses that matches the specified type. 098 */ 099 public List<Address> getAddressesOfType(Type type) { 100 List<Address> answer = new ArrayList<>(addresses.size()); 101 for (Address address : addresses) { 102 if (address.getType().equals(type)) { 103 answer.add(address); 104 } 105 } 106 107 return answer; 108 } 109 110 @Override 111 public String getElementName() { 112 return ELEMENT; 113 } 114 115 @Override 116 public String getNamespace() { 117 return NAMESPACE; 118 } 119 120 @Override 121 public XmlStringBuilder toXML(String enclosingNamespace) { 122 XmlStringBuilder buf = new XmlStringBuilder(this); 123 buf.rightAngleBracket(); 124 // Loop through all the addresses and append them to the string buffer 125 for (Address address : addresses) { 126 buf.append(address.toXML(null)); 127 } 128 buf.closeElement(this); 129 return buf; 130 } 131 132 public static final class Address implements NamedElement { 133 134 public static final String ELEMENT = "address"; 135 136 private final Type type; 137 private Jid jid; 138 private String node; 139 private String description; 140 private boolean delivered; 141 private String uri; 142 143 private Address(Type type) { 144 this.type = type; 145 } 146 147 public Type getType() { 148 return type; 149 } 150 151 public Jid getJid() { 152 return jid; 153 } 154 155 private void setJid(Jid jid) { 156 this.jid = jid; 157 } 158 159 public String getNode() { 160 return node; 161 } 162 163 private void setNode(String node) { 164 this.node = node; 165 } 166 167 public String getDescription() { 168 return description; 169 } 170 171 private void setDescription(String description) { 172 this.description = description; 173 } 174 175 public boolean isDelivered() { 176 return delivered; 177 } 178 179 private void setDelivered(boolean delivered) { 180 this.delivered = delivered; 181 } 182 183 public String getUri() { 184 return uri; 185 } 186 187 private void setUri(String uri) { 188 this.uri = uri; 189 } 190 191 @Override 192 public String getElementName() { 193 return ELEMENT; 194 } 195 196 @Override 197 public XmlStringBuilder toXML(String enclosingNamespace) { 198 XmlStringBuilder buf = new XmlStringBuilder(); 199 buf.halfOpenElement(this).attribute("type", type); 200 buf.optAttribute("jid", jid); 201 buf.optAttribute("node", node); 202 buf.optAttribute("desc", description); 203 if (description != null && description.trim().length() > 0) { 204 buf.append(" desc=\""); 205 buf.append(description).append('"'); 206 } 207 buf.optBooleanAttribute("delivered", delivered); 208 buf.optAttribute("uri", uri); 209 buf.closeEmptyElement(); 210 return buf; 211 } 212 } 213}