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 org.jivesoftware.smack.util.StringUtils; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.*; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Represents XMPP message packets. A message can be one of several types: 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <ul> 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Message.Type.NORMAL -- (Default) a normal text message used in email like interface. 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Message.Type.CHAT -- a typically short text message used in line-by-line chat interfaces. 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Message.Type.GROUP_CHAT -- a chat message sent to a groupchat server for group chats. 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Message.Type.HEADLINE -- a text message to be displayed in scrolling marquee displays. 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Message.Type.ERROR -- indicates a messaging error. 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </ul> 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * For each message type, different message fields are typically used as follows: 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p> 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <table border="1"> 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tr><td> </td><td colspan="5"><b>Message type</b></td></tr> 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tr><td><i>Field</i></td><td><b>Normal</b></td><td><b>Chat</b></td><td><b>Group Chat</b></td><td><b>Headline</b></td><td><b>XMPPError</b></td></tr> 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tr><td><i>subject</i></td> <td>SHOULD</td><td>SHOULD NOT</td><td>SHOULD NOT</td><td>SHOULD NOT</td><td>SHOULD NOT</td></tr> 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tr><td><i>thread</i></td> <td>OPTIONAL</td><td>SHOULD</td><td>OPTIONAL</td><td>OPTIONAL</td><td>SHOULD NOT</td></tr> 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tr><td><i>body</i></td> <td>SHOULD</td><td>SHOULD</td><td>SHOULD</td><td>SHOULD</td><td>SHOULD NOT</td></tr> 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tr><td><i>error</i></td> <td>MUST NOT</td><td>MUST NOT</td><td>MUST NOT</td><td>MUST NOT</td><td>MUST</td></tr> 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </table> 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Matt Tucker 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class Message extends Packet { 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Type type = Type.normal; 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String thread = null; 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String language; 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final Set<Subject> subjects = new HashSet<Subject>(); 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final Set<Body> bodies = new HashSet<Body>(); 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates a new, "normal" message. 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Message() { 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates a new "normal" message to the specified recipient. 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param to the recipient of the message. 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Message(String to) { 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen setTo(to); 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates a new message of the specified type to a recipient. 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param to the user to send the message to. 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type the message type. 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Message(String to, Type type) { 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen setTo(to); 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.type = type; 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the type of the message. If no type has been set this method will return {@link 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * org.jivesoftware.smack.packet.Message.Type#normal}. 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the type of the message. 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Type getType() { 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return type; 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the type of the message. 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type the type of the message. 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException if null is passed in as the type 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setType(Type type) { 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (type == null) { 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("Type cannot be null."); 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.type = type; 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the default subject of the message, or null if the subject has not been set. 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The subject is a short description of message contents. 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p> 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The default subject of a message is the subject that corresponds to the message's language. 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (see {@link #getLanguage()}) or if no language is set to the applications default 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * language (see {@link Packet#getDefaultLanguage()}). 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the subject of the message. 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getSubject() { 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return getSubject(null); 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the subject corresponding to the language. If the language is null, the method result 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * will be the same as {@link #getSubject()}. Null will be returned if the language does not have 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * a corresponding subject. 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the language of the subject to return. 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the subject related to the passed in language. 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getSubject(String language) { 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Subject subject = getMessageSubject(language); 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return subject == null ? null : subject.subject; 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Subject getMessageSubject(String language) { 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = determineLanguage(language); 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Subject subject : subjects) { 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language.equals(subject.language)) { 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return subject; 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns a set of all subjects in this Message, including the default message subject accessible 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * from {@link #getSubject()}. 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a collection of all subjects in this message. 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Collection<Subject> getSubjects() { 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableCollection(subjects); 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the subject of the message. The subject is a short description of 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * message contents. 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param subject the subject of the message. 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setSubject(String subject) { 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (subject == null) { 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen removeSubject(""); // use empty string because #removeSubject(null) is ambiguous 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addSubject(null, subject); 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a subject with a corresponding language. 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the language of the subject being added. 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param subject the subject being added to the message. 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the new {@link org.jivesoftware.smack.packet.Message.Subject} 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws NullPointerException if the subject is null, a null pointer exception is thrown 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Subject addSubject(String language, String subject) { 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = determineLanguage(language); 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Subject messageSubject = new Subject(language, subject); 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen subjects.add(messageSubject); 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return messageSubject; 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the subject with the given language from the message. 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the language of the subject which is to be removed 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if a subject was removed and false if it was not. 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean removeSubject(String language) { 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = determineLanguage(language); 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Subject subject : subjects) { 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language.equals(subject.language)) { 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return subjects.remove(subject); 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the subject from the message and returns true if the subject was removed. 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param subject the subject being removed from the message. 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the subject was successfully removed and false if it was not. 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean removeSubject(Subject subject) { 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return subjects.remove(subject); 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns all the languages being used for the subjects, not including the default subject. 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the languages being used for the subjects. 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Collection<String> getSubjectLanguages() { 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Subject defaultSubject = getMessageSubject(null); 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List<String> languages = new ArrayList<String>(); 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Subject subject : subjects) { 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!subject.equals(defaultSubject)) { 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen languages.add(subject.language); 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableCollection(languages); 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the default body of the message, or null if the body has not been set. The body 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * is the main message contents. 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p> 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The default body of a message is the body that corresponds to the message's language. 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (see {@link #getLanguage()}) or if no language is set to the applications default 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * language (see {@link Packet#getDefaultLanguage()}). 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the body of the message. 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getBody() { 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return getBody(null); 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the body corresponding to the language. If the language is null, the method result 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * will be the same as {@link #getBody()}. Null will be returned if the language does not have 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * a corresponding body. 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the language of the body to return. 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the body related to the passed in language. 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getBody(String language) { 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Body body = getMessageBody(language); 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return body == null ? null : body.message; 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Body getMessageBody(String language) { 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = determineLanguage(language); 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Body body : bodies) { 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language.equals(body.language)) { 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return body; 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns a set of all bodies in this Message, including the default message body accessible 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * from {@link #getBody()}. 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a collection of all bodies in this Message. 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Collection<Body> getBodies() { 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableCollection(bodies); 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the body of the message. The body is the main message contents. 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param body the body of the message. 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setBody(String body) { 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (body == null) { 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen removeBody(""); // use empty string because #removeBody(null) is ambiguous 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addBody(null, body); 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a body with a corresponding language. 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the language of the body being added. 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param body the body being added to the message. 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the new {@link org.jivesoftware.smack.packet.Message.Body} 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws NullPointerException if the body is null, a null pointer exception is thrown 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Body addBody(String language, String body) { 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = determineLanguage(language); 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Body messageBody = new Body(language, body); 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bodies.add(messageBody); 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return messageBody; 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the body with the given language from the message. 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the language of the body which is to be removed 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if a body was removed and false if it was not. 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean removeBody(String language) { 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = determineLanguage(language); 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Body body : bodies) { 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language.equals(body.language)) { 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return bodies.remove(body); 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the body from the message and returns true if the body was removed. 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param body the body being removed from the message. 325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the body was successfully removed and false if it was not. 326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean removeBody(Body body) { 329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return bodies.remove(body); 330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns all the languages being used for the bodies, not including the default body. 334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the languages being used for the bodies. 336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Collection<String> getBodyLanguages() { 339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Body defaultBody = getMessageBody(null); 340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List<String> languages = new ArrayList<String>(); 341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Body body : bodies) { 342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!body.equals(defaultBody)) { 343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen languages.add(body.language); 344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableCollection(languages); 347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the thread id of the message, which is a unique identifier for a sequence 351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * of "chat" messages. If no thread id is set, <tt>null</tt> will be returned. 352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the thread id of the message, or <tt>null</tt> if it doesn't exist. 354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getThread() { 356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return thread; 357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the thread id of the message, which is a unique identifier for a sequence 361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * of "chat" messages. 362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param thread the thread id of the message. 364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setThread(String thread) { 366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.thread = thread; 367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the xml:lang of this Message. 371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the xml:lang of this Message. 373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getLanguage() { 376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return language; 377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the xml:lang of this Message. 381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param language the xml:lang of this Message. 383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @since 3.0.2 384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setLanguage(String language) { 386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.language = language; 387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String determineLanguage(String language) { 390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // empty string is passed by #setSubject() and #setBody() and is the same as null 392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen language = "".equals(language) ? null : language; 393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // if given language is null check if message language is set 395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language == null && this.language != null) { 396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return this.language; 397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (language == null) { 399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return getDefaultLanguage(); 400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return language; 403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String toXML() { 408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuilder buf = new StringBuilder(); 409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<message"); 410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (getXmlns() != null) { 411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(" xmlns=\"").append(getXmlns()).append("\""); 412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language != null) { 414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(" xml:lang=\"").append(getLanguage()).append("\""); 415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (getPacketID() != null) { 417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(" id=\"").append(getPacketID()).append("\""); 418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (getTo() != null) { 420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(" to=\"").append(StringUtils.escapeForXML(getTo())).append("\""); 421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (getFrom() != null) { 423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(" from=\"").append(StringUtils.escapeForXML(getFrom())).append("\""); 424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (type != Type.normal) { 426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(" type=\"").append(type).append("\""); 427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(">"); 429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the subject in the default language 430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Subject defaultSubject = getMessageSubject(null); 431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (defaultSubject != null) { 432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<subject>").append(StringUtils.escapeForXML(defaultSubject.subject)).append("</subject>"); 433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the subject in other languages 435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Subject subject : getSubjects()) { 436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Skip the default language 437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if(subject.equals(defaultSubject)) 438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen continue; 439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<subject xml:lang=\"").append(subject.language).append("\">"); 440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(StringUtils.escapeForXML(subject.subject)); 441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("</subject>"); 442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the body in the default language 444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Body defaultBody = getMessageBody(null); 445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (defaultBody != null) { 446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<body>").append(StringUtils.escapeForXML(defaultBody.message)).append("</body>"); 447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the bodies in other languages 449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Body body : getBodies()) { 450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Skip the default language 451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if(body.equals(defaultBody)) 452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen continue; 453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<body xml:lang=\"").append(body.getLanguage()).append("\">"); 454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(StringUtils.escapeForXML(body.getMessage())); 455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("</body>"); 456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (thread != null) { 458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("<thread>").append(thread).append("</thread>"); 459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Append the error subpacket if the message type is an error. 461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (type == Type.error) { 462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen XMPPError error = getError(); 463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (error != null) { 464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(error.toXML()); 465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add packet extensions, if any are defined. 468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append(getExtensionsXML()); 469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen buf.append("</message>"); 470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return buf.toString(); 471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean equals(Object o) { 475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (this == o) return true; 476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (o == null || getClass() != o.getClass()) return false; 477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Message message = (Message) o; 479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if(!super.equals(message)) { return false; } 481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (bodies.size() != message.bodies.size() || !bodies.containsAll(message.bodies)) { 482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language != null ? !language.equals(message.language) : message.language != null) { 485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (subjects.size() != message.subjects.size() || !subjects.containsAll(message.subjects)) { 488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (thread != null ? !thread.equals(message.thread) : message.thread != null) { 491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return type == message.type; 494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int hashCode() { 498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int result; 499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = (type != null ? type.hashCode() : 0); 500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + subjects.hashCode(); 501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + (thread != null ? thread.hashCode() : 0); 502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + (language != null ? language.hashCode() : 0); 503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = 31 * result + bodies.hashCode(); 504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return result; 505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Represents a message subject, its language and the content of the subject. 509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 510d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static class Subject { 511d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 512d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String subject; 513d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String language; 514d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 515d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Subject(String language, String subject) { 516d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language == null) { 517d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Language cannot be null."); 518d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 519d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (subject == null) { 520d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Subject cannot be null."); 521d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 522d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.language = language; 523d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.subject = subject; 524d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 525d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 526d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 527d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the language of this message subject. 528d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 529d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the language of this message subject. 530d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 531d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getLanguage() { 532d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return language; 533d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 534d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 535d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 536d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the subject content. 537d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 538d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the content of the subject. 539d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 540d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getSubject() { 541d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return subject; 542d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 543d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 544d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 545d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int hashCode() { 546d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final int prime = 31; 547d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int result = 1; 548d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = prime * result + this.language.hashCode(); 549d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = prime * result + this.subject.hashCode(); 550d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return result; 551d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 552d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 553d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean equals(Object obj) { 554d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (this == obj) { 555d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return true; 556d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 557d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (obj == null) { 558d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 559d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 560d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (getClass() != obj.getClass()) { 561d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 562d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 563d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Subject other = (Subject) obj; 564d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // simplified comparison because language and subject are always set 565d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return this.language.equals(other.language) && this.subject.equals(other.subject); 566d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 567d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 568d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 569d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 570d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 571d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Represents a message body, its language and the content of the message. 572d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 573d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static class Body { 574d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 575d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String message; 576d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String language; 577d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 578d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Body(String language, String message) { 579d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (language == null) { 580d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Language cannot be null."); 581d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 582d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (message == null) { 583d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Message cannot be null."); 584d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 585d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.language = language; 586d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.message = message; 587d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 588d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 589d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 590d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the language of this message body. 591d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 592d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the language of this message body. 593d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 594d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getLanguage() { 595d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return language; 596d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 597d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 598d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 599d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the message content. 600d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 601d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the content of the message. 602d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 603d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getMessage() { 604d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return message; 605d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 606d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 607d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int hashCode() { 608d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen final int prime = 31; 609d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int result = 1; 610d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = prime * result + this.language.hashCode(); 611d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen result = prime * result + this.message.hashCode(); 612d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return result; 613d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 614d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 615d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean equals(Object obj) { 616d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (this == obj) { 617d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return true; 618d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 619d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (obj == null) { 620d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 621d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 622d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (getClass() != obj.getClass()) { 623d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 624d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 625d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Body other = (Body) obj; 626d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // simplified comparison because language and message are always set 627d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return this.language.equals(other.language) && this.message.equals(other.message); 628d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 629d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 630d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 631d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 632d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 633d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Represents the type of a message. 634d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 635d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public enum Type { 636d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 637d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 638d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (Default) a normal text message used in email like interface. 639d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 640d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen normal, 641d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 642d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 643d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Typically short text message used in line-by-line chat interfaces. 644d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 645d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen chat, 646d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 647d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 648d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Chat message sent to a groupchat server for group chats. 649d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 650d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen groupchat, 651d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 652d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 653d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Text message to be displayed in scrolling marquee displays. 654d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 655d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen headline, 656d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 657d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 658d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * indicates a messaging error. 659d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 660d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen error; 661d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 662d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static Type fromString(String name) { 663d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 664d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Type.valueOf(name); 665d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 666d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 667d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return normal; 668d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 669d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 670d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 671d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 672d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 673