Packet.java revision d7955ce24d294fb2014c59d11fca184471056f44
1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$ 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$ 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software. 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License. 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * http://www.apache.org/licenses/LICENSE-2.0 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS, 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smack.packet; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.ByteArrayOutputStream; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.ObjectOutputStream; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.Serializable; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.text.DateFormat; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.text.SimpleDateFormat; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.ArrayList; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Collection; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Collections; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.HashMap; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.HashSet; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Map; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.TimeZone; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.CopyOnWriteArrayList; 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.util.StringUtils; 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Base class for XMPP packets. Every packet has a unique ID (which is automatically 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * generated, but can be overriden). Optionally, the "to" and "from" fields can be set, 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * as well as an arbitrary number of properties. 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Properties provide an easy mechanism for clients to share data. Each property has a 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * String name, and a value that is a Java primitive (int, long, float, double, boolean) 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * or any Serializable object (a Java object is Serializable when it implements the 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Serializable interface). 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Matt Tucker 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic abstract class Packet { 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected static final String DEFAULT_LANGUAGE = 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen java.util.Locale.getDefault().getLanguage().toLowerCase(); 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static String DEFAULT_XML_NS = null; 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Constant used as packetID to indicate that a packet has no id. To indicate that a packet 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * has no id set this constant as the packet's id. When the packet is asked for its id the 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * answer will be <tt>null</tt>. 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static final String ID_NOT_AVAILABLE = "ID_NOT_AVAILABLE"; 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Date format as defined in XEP-0082 - XMPP Date and Time Profiles. 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The time zone is set to UTC. 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p> 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Date formats are not synchronized. Since multiple threads access the format concurrently, 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * it must be synchronized externally. 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static final DateFormat XEP_0082_UTC_FORMAT = new SimpleDateFormat( 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen static { 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen XEP_0082_UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A prefix helps to make sure that ID's are unique across mutliple instances. 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static String prefix = StringUtils.randomString(5) + "-"; 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Keeps track of the current increment, which is appended to the prefix to 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * forum a unique ID. 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static long id = 0; 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String xmlns = DEFAULT_XML_NS; 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the next unique id. Each id made up of a short alphanumeric 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * prefix along with a unique numeric value. 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the next id. 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static synchronized String nextID() { 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return prefix + Long.toString(id++); 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static void setDefaultXmlns(String defaultXmlns) { 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DEFAULT_XML_NS = defaultXmlns; 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String packetID = null; 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String to = null; 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String from = null; 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final List<PacketExtension> packetExtensions 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen = new CopyOnWriteArrayList<PacketExtension>(); 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final Map<String,Object> properties = new HashMap<String, Object>(); 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private XMPPError error = null; 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Packet() { 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Packet(Packet p) { 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetID = p.getPacketID(); 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen to = p.getTo(); 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen from = p.getFrom(); 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen xmlns = p.xmlns; 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error = p.error; 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Copy extensions 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (PacketExtension pe : p.getExtensions()) { 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addExtension(pe); 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the unique ID of the packet. The returned value could be <tt>null</tt> when 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * ID_NOT_AVAILABLE was set as the packet's id. 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the packet's unique ID or <tt>null</tt> if the packet's id is not available. 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getPacketID() { 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (ID_NOT_AVAILABLE.equals(packetID)) { 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetID == null) { 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetID = nextID(); 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return packetID; 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the unique ID of the packet. To indicate that a packet has no id 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * pass the constant ID_NOT_AVAILABLE as the packet's id value. 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetID the unique ID for the packet. 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setPacketID(String packetID) { 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.packetID = packetID; 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns who the packet is being sent "to", or <tt>null</tt> if 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the value is not set. The XMPP protocol often makes the "to" 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * attribute optional, so it does not always need to be set.<p> 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The StringUtils class provides several useful methods for dealing with 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * XMPP addresses such as parsing the 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseBareAddress(String) bare address}, 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseName(String) user name}, 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseServer(String) server}, and 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseResource(String) resource}. 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return who the packet is being sent to, or <tt>null</tt> if the 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * value has not been set. 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getTo() { 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return to; 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets who the packet is being sent "to". The XMPP protocol often makes 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the "to" attribute optional, so it does not always need to be set. 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param to who the packet is being sent to. 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setTo(String to) { 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.to = to; 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns who the packet is being sent "from" or <tt>null</tt> if 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the value is not set. The XMPP protocol often makes the "from" 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * attribute optional, so it does not always need to be set.<p> 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The StringUtils class provides several useful methods for dealing with 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * XMPP addresses such as parsing the 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseBareAddress(String) bare address}, 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseName(String) user name}, 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseServer(String) server}, and 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link StringUtils#parseResource(String) resource}. 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return who the packet is being sent from, or <tt>null</tt> if the 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * value has not been set. 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getFrom() { 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return from; 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets who the packet is being sent "from". The XMPP protocol often 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * makes the "from" attribute optional, so it does not always need to 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be set. 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param from who the packet is being sent to. 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setFrom(String from) { 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.from = from; 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the error associated with this packet, or <tt>null</tt> if there are 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * no errors. 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the error sub-packet or <tt>null</tt> if there isn't an error. 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public XMPPError getError() { 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return error; 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the error for this packet. 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param error the error to associate with this packet. 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setError(XMPPError error) { 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.error = error; 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an unmodifiable collection of the packet extensions attached to the packet. 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the packet extensions. 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public synchronized Collection<PacketExtension> getExtensions() { 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetExtensions == null) { 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.emptyList(); 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableList(new ArrayList<PacketExtension>(packetExtensions)); 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the first extension of this packet that has the given namespace. 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param namespace the namespace of the extension that is desired. 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the packet extension with the given namespace. 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public PacketExtension getExtension(String namespace) { 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return getExtension(null, namespace); 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the first packet extension that matches the specified element name and 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * namespace, or <tt>null</tt> if it doesn't exist. If the provided elementName is null 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * than only the provided namespace is attempted to be matched. Packet extensions are 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * are arbitrary XML sub-documents in standard XMPP packets. By default, a 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * DefaultPacketExtension instance will be returned for each extension. However, 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * PacketExtensionProvider instances can be registered with the 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link org.jivesoftware.smack.provider.ProviderManager ProviderManager} 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * class to handle custom parsing. In that case, the type of the Object 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * will be determined by the provider. 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param elementName the XML element name of the packet extension. (May be null) 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param namespace the XML element namespace of the packet extension. 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the extension, or <tt>null</tt> if it doesn't exist. 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public PacketExtension getExtension(String elementName, String namespace) { 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (namespace == null) { 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (PacketExtension ext : packetExtensions) { 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if ((elementName == null || elementName.equals(ext.getElementName())) 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen && namespace.equals(ext.getNamespace())) 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return ext; 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a packet extension to the packet. Does nothing if extension is null. 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param extension a packet extension. 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addExtension(PacketExtension extension) { 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (extension == null) return; 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetExtensions.add(extension); 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a collection of packet extensions to the packet. Does nothing if extensions is null. 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param extensions a collection of packet extensions 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addExtensions(Collection<PacketExtension> extensions) { 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (extensions == null) return; 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetExtensions.addAll(extensions); 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a packet extension from the packet. 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param extension the packet extension to remove. 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removeExtension(PacketExtension extension) { 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetExtensions.remove(extension); 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the packet property with the specified name or <tt>null</tt> if the 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * property doesn't exist. Property values that were originally primitives will 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be returned as their object equivalent. For example, an int property will be 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * returned as an Integer, a double as a Double, etc. 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name the name of the property. 324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the property, or <tt>null</tt> if the property doesn't exist. 325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public synchronized Object getProperty(String name) { 327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (properties == null) { 328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return properties.get(name); 331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets a property with an Object as the value. The value must be Serializable 335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * or an IllegalArgumentException will be thrown. 336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name the name of the property. 338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param value the value of the property. 339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public synchronized void setProperty(String name, Object value) { 341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!(value instanceof Serializable)) { 342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("Value must be serialiazble"); 343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen properties.put(name, value); 345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Deletes a property. 349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name the name of the property to delete. 351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public synchronized void deleteProperty(String name) { 353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (properties == null) { 354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen properties.remove(name); 357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an unmodifiable collection of all the property names that are set. 361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return all property names. 363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public synchronized Collection<String> getPropertyNames() { 365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (properties == null) { 366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.emptySet(); 367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableSet(new HashSet<String>(properties.keySet())); 369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the packet as XML. Every concrete extension of Packet must implement 373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * this method. In addition to writing out packet-specific data, every sub-class 374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * should also write out the error and the extensions data if they are defined. 375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the XML format of the packet as a String. 377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract String toXML(); 379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the extension sub-packets (including properties data) as an XML 382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * String, or the Empty String if there are no packet extensions. 383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the extension sub-packets as XML or the Empty String if there 385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * are no packet extensions. 386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected synchronized String getExtensionsXML() { 388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder buf = new StringBuilder(); 389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add in all standard extension sub-packets. 390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (PacketExtension extension : getExtensions()) { 391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(extension.toXML()); 392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add in packet properties. 394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (properties != null && !properties.isEmpty()) { 395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<properties xmlns=\"http://www.jivesoftware.com/xmlns/xmpp/properties\">"); 396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Loop through all properties and write them out. 397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (String name : getPropertyNames()) { 398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Object value = getProperty(name); 399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<property>"); 400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<name>").append(StringUtils.escapeForXML(name)).append("</name>"); 401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<value type=\""); 402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (value instanceof Integer) { 403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("integer\">").append(value).append("</value>"); 404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (value instanceof Long) { 406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("long\">").append(value).append("</value>"); 407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (value instanceof Float) { 409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("float\">").append(value).append("</value>"); 410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (value instanceof Double) { 412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("double\">").append(value).append("</value>"); 413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (value instanceof Boolean) { 415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("boolean\">").append(value).append("</value>"); 416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (value instanceof String) { 418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("string\">"); 419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(StringUtils.escapeForXML((String)value)); 420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("</value>"); 421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Otherwise, it's a generic Serializable object. Serialized objects are in 423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // a binary format, which won't work well inside of XML. Therefore, we base-64 424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // encode the binary data before adding it. 425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ByteArrayOutputStream byteStream = null; 427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ObjectOutputStream out = null; 428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byteStream = new ByteArrayOutputStream(); 430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out = new ObjectOutputStream(byteStream); 431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeObject(value); 432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("java-object\">"); 433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String encodedVal = StringUtils.encodeBase64(byteStream.toByteArray()); 434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(encodedVal).append("</value>"); 435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen e.printStackTrace(); 438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen finally { 440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (out != null) { 441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.close(); 443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Ignore. 446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (byteStream != null) { 449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byteStream.close(); 451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Ignore. 454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("</property>"); 459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("</properties>"); 461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return buf.toString(); 463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getXmlns() { 466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return this.xmlns; 467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the default language used for all messages containing localized content. 471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the default language 473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static String getDefaultLanguage() { 475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return DEFAULT_LANGUAGE; 476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean equals(Object o) { 479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (this == o) return true; 480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (o == null || getClass() != o.getClass()) return false; 481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Packet packet = (Packet) o; 483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (error != null ? !error.equals(packet.error) : packet.error != null) { return false; } 485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (from != null ? !from.equals(packet.from) : packet.from != null) { return false; } 486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!packetExtensions.equals(packet.packetExtensions)) { return false; } 487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetID != null ? !packetID.equals(packet.packetID) : packet.packetID != null) { 488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (properties != null ? !properties.equals(packet.properties) 491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen : packet.properties != null) { 492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (to != null ? !to.equals(packet.to) : packet.to != null) { return false; } 495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null); 496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int hashCode() { 499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int result; 500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = (xmlns != null ? xmlns.hashCode() : 0); 501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + (packetID != null ? packetID.hashCode() : 0); 502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + (to != null ? to.hashCode() : 0); 503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + (from != null ? from.hashCode() : 0); 504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + packetExtensions.hashCode(); 505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + properties.hashCode(); 506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + (error != null ? error.hashCode() : 0); 507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return result; 508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 510