diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java index 9b2d392a0..c424e339e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java @@ -17,12 +17,8 @@ package org.jivesoftware.smack.packet; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Set; import javax.xml.namespace.QName; @@ -186,59 +182,6 @@ public final class Message extends MessageOrPresence this.type = type; } - /** - * Returns the default subject of the message, or null if the subject has not been set. - * The subject is a short description of message contents. - *

- * The default subject of a message is the subject that corresponds to the message's language. - * (see {@link #getLanguage()}) or if no language is set to the applications default - * language (see {@link Stanza#getDefaultLanguage()}). - * - * @return the subject of the message. - */ - public String getSubject() { - return getSubject(null); - } - - /** - * Returns the subject corresponding to the language. If the language is null, the method result - * will be the same as {@link #getSubject()}. Null will be returned if the language does not have - * a corresponding subject. - * - * @param language the language of the subject to return. - * @return the subject related to the passed in language. - */ - public String getSubject(String language) { - Subject subject = getMessageSubject(language); - return subject == null ? null : subject.subject; - } - - private Subject getMessageSubject(String language) { - language = determineLanguage(language); - for (Subject subject : getSubjects()) { - if (Objects.equals(language, subject.language) - || (subject.language == null && Objects.equals(this.language, language))) { - return subject; - } - } - return null; - } - - /** - * Returns a set of all subjects in this Message, including the default message subject accessible - * from {@link #getSubject()}. - * - * @return a collection of all subjects in this message. - */ - public Set getSubjects() { - List subjectList = getExtensions(Subject.class); - - Set subjects = new HashSet<>(subjectList.size()); - subjects.addAll(subjectList); - - return subjects; - } - /** * Sets the subject of the message. The subject is a short description of * message contents. @@ -267,7 +210,7 @@ public final class Message extends MessageOrPresence @Deprecated // TODO: Remove when stanza builder is ready. public Subject addSubject(String language, String subject) { - language = determineLanguage(language); + language = Stanza.determineLanguage(this, language); List currentSubjects = getExtensions(Subject.class); for (Subject currentSubject : currentSubjects) { @@ -290,7 +233,7 @@ public final class Message extends MessageOrPresence @Deprecated // TODO: Remove when stanza builder is ready. public boolean removeSubject(String language) { - language = determineLanguage(language); + language = Stanza.determineLanguage(this, language); for (Subject subject : getExtensions(Subject.class)) { if (language.equals(subject.language)) { return removeSubject(subject); @@ -311,77 +254,6 @@ public final class Message extends MessageOrPresence return removeExtension(subject) != null; } - /** - * Returns all the languages being used for the subjects, not including the default subject. - * - * @return the languages being used for the subjects. - */ - public List getSubjectLanguages() { - Subject defaultSubject = getMessageSubject(null); - List languages = new ArrayList(); - for (Subject subject : getExtensions(Subject.class)) { - if (!subject.equals(defaultSubject)) { - languages.add(subject.language); - } - } - return Collections.unmodifiableList(languages); - } - - /** - * Returns the default body of the message, or null if the body has not been set. The body - * is the main message contents. - *

- * The default body of a message is the body that corresponds to the message's language. - * (see {@link #getLanguage()}) or if no language is set to the applications default - * language (see {@link Stanza#getDefaultLanguage()}). - * - * @return the body of the message. - */ - public String getBody() { - return getBody(language); - } - - /** - * Returns the body corresponding to the language. If the language is null, the method result - * will be the same as {@link #getBody()}. Null will be returned if the language does not have - * a corresponding body. - * - * @param language the language of the body to return. - * @return the body related to the passed in language. - * @since 3.0.2 - */ - public String getBody(String language) { - Body body = getMessageBody(language); - return body == null ? null : body.message; - } - - private Body getMessageBody(String language) { - language = determineLanguage(language); - for (Body body : getBodies()) { - if (Objects.equals(language, body.language) || (language != null && language.equals(this.language) && body.language == null)) { - return body; - } - } - return null; - } - - /** - * Returns a set of all bodies in this Message, including the default message body accessible - * from {@link #getBody()}. - * - * @return a collection of all bodies in this Message. - * @since 3.0.2 - */ - public Set getBodies() { - List bodiesList = getExtensions(Body.ELEMENT, Body.NAMESPACE); - Set resultSet = new HashSet<>(bodiesList.size()); - for (ExtensionElement extensionElement : bodiesList) { - Body body = (Body) extensionElement; - resultSet.add(body); - } - return resultSet; - } - /** * Sets the body of the message. * @@ -431,7 +303,7 @@ public final class Message extends MessageOrPresence @Deprecated // TODO: Remove when stanza builder is ready. public Body addBody(String language, String body) { - language = determineLanguage(language); + language = Stanza.determineLanguage(this, language); removeBody(language); @@ -450,7 +322,7 @@ public final class Message extends MessageOrPresence @Deprecated // TODO: Remove when stanza builder is ready. public boolean removeBody(String language) { - language = determineLanguage(language); + language = Stanza.determineLanguage(this, language); for (Body body : getBodies()) { String bodyLanguage = body.getLanguage(); if (Objects.equals(bodyLanguage, language)) { @@ -476,37 +348,6 @@ public final class Message extends MessageOrPresence return removedElement != null; } - /** - * Returns all the languages being used for the bodies, not including the default body. - * - * @return the languages being used for the bodies. - * @since 3.0.2 - */ - public List getBodyLanguages() { - Body defaultBody = getMessageBody(null); - List languages = new ArrayList(); - for (Body body : getBodies()) { - if (!body.equals(defaultBody)) { - languages.add(body.language); - } - } - return Collections.unmodifiableList(languages); - } - - /** - * Returns the thread id of the message, which is a unique identifier for a sequence - * of "chat" messages. If no thread id is set, null will be returned. - * - * @return the thread id of the message, or null if it doesn't exist. - */ - public String getThread() { - Message.Thread thread = getExtension(Message.Thread.class); - if (thread == null) { - return null; - } - return thread.getThread(); - } - /** * Sets the thread id of the message, which is a unique identifier for a sequence * of "chat" messages. @@ -520,18 +361,6 @@ public final class Message extends MessageOrPresence addExtension(new Message.Thread(thread)); } - private String determineLanguage(String language) { - - // empty string is passed by #setSubject() and #setBody() and is the same as null - language = "".equals(language) ? null : language; - - // if given language is null check if message language is set - if (language == null && this.language != null) { - return this.language; - } - return language; - } - @Override public String getElementName() { return ELEMENT; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java index 046b9274f..62d78b829 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java @@ -1,6 +1,6 @@ /** * - * Copyright 2019 Florian Schmaus + * Copyright 2003-2007 Jive Software, 2019-2020 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,15 @@ */ package org.jivesoftware.smack.packet; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.jivesoftware.smack.packet.Message.Subject; +import org.jivesoftware.smack.util.Objects; + public interface MessageView extends StanzaView { /** @@ -26,4 +35,158 @@ public interface MessageView extends StanzaView { */ Message.Type getType(); + /** + * Returns the default subject of the message, or null if the subject has not been set. + * The subject is a short description of message contents. + *

+ * The default subject of a message is the subject that corresponds to the message's language. + * (see {@link #getLanguage()}) or if no language is set to the applications default + * language (see {@link Stanza#getDefaultLanguage()}). + * + * @return the subject of the message. + */ + default String getSubject() { + return getSubject(null); + } + + /** + * Returns the subject corresponding to the language. If the language is null, the method result + * will be the same as {@link #getSubject()}. Null will be returned if the language does not have + * a corresponding subject. + * + * @param language the language of the subject to return. + * @return the subject related to the passed in language. + */ + default String getSubject(String language) { + Subject subject = getMessageSubject(language); + return subject == null ? null : subject.getSubject(); + } + + default Message.Subject getMessageSubject(String language) { + language = Stanza.determineLanguage(this, language); + for (Message.Subject subject : getSubjects()) { + if (Objects.equals(language, subject.getLanguage()) + || (subject.getLanguage() == null && Objects.equals(getLanguage(), language))) { + return subject; + } + } + return null; + } + + /** + * Returns a set of all subjects in this Message, including the default message subject accessible + * from {@link #getSubject()}. + * + * @return a collection of all subjects in this message. + */ + default Set getSubjects() { + List subjectList = getExtensions(Subject.class); + + Set subjects = new HashSet<>(subjectList.size()); + subjects.addAll(subjectList); + + return subjects; + } + + /** + * Returns all the languages being used for the subjects, not including the default subject. + * + * @return the languages being used for the subjects. + */ + default List getSubjectLanguages() { + Message.Subject defaultSubject = getMessageSubject(null); + List languages = new ArrayList(); + for (Message.Subject subject : getExtensions(Message.Subject.class)) { + if (!subject.equals(defaultSubject)) { + languages.add(subject.getLanguage()); + } + } + return Collections.unmodifiableList(languages); + } + + /** + * Returns the default body of the message, or null if the body has not been set. The body + * is the main message contents. + *

+ * The default body of a message is the body that corresponds to the message's language. + * (see {@link #getLanguage()}) or if no language is set to the applications default + * language (see {@link Stanza#getDefaultLanguage()}). + * + * @return the body of the message. + */ + default String getBody() { + return getBody(getLanguage()); + } + + /** + * Returns the body corresponding to the language. If the language is null, the method result + * will be the same as {@link #getBody()}. Null will be returned if the language does not have + * a corresponding body. + * + * @param language the language of the body to return. + * @return the body related to the passed in language. + * @since 3.0.2 + */ + default String getBody(String language) { + Message.Body body = getMessageBody(language); + return body == null ? null : body.getMessage(); + } + + default Message.Body getMessageBody(String language) { + language = Stanza.determineLanguage(this, language); + for (Message.Body body : getBodies()) { + if (Objects.equals(language, body.getLanguage()) || (language != null && language.equals(getLanguage()) && body.getLanguage() == null)) { + return body; + } + } + return null; + } + + /** + * Returns a set of all bodies in this Message, including the default message body accessible + * from {@link #getBody()}. + * + * @return a collection of all bodies in this Message. + * @since 3.0.2 + */ + default Set getBodies() { + List bodiesList = getExtensions(Message.Body.QNAME); + Set resultSet = new HashSet<>(bodiesList.size()); + for (ExtensionElement extensionElement : bodiesList) { + Message.Body body = (Message.Body) extensionElement; + resultSet.add(body); + } + return resultSet; + } + + /** + * Returns all the languages being used for the bodies, not including the default body. + * + * @return the languages being used for the bodies. + * @since 3.0.2 + */ + default List getBodyLanguages() { + Message.Body defaultBody = getMessageBody(null); + List languages = new ArrayList(); + for (Message.Body body : getBodies()) { + if (!body.equals(defaultBody)) { + languages.add(body.getLanguage()); + } + } + return Collections.unmodifiableList(languages); + } + + /** + * Returns the thread id of the message, which is a unique identifier for a sequence + * of "chat" messages. If no thread id is set, null will be returned. + * + * @return the thread id of the message, or null if it doesn't exist. + */ + default String getThread() { + Message.Thread thread = getExtension(Message.Thread.class); + if (thread == null) { + return null; + } + return thread.getThread(); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java index ee9377d1a..bce5ba0f5 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java @@ -575,4 +575,18 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { xml.append(error); } } + + /** + * Return the provided non-empty language, or use this {@link XmlLangElement} language (if set). + * + * @param language the provided language, may be the empty string or null. + * @return the provided language or this element's language (if set). + */ + static String determineLanguage(XmlLangElement xmlLangElement, String language) { + if (language != null && !language.isEmpty()) { + return language; + } + + return xmlLangElement.getLanguage(); + } }