001/**
002 *
003 * Copyright 2018 Paul Schaub
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.spoiler.element;
018
019import java.util.Collections;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023
024import org.jivesoftware.smack.packet.ExtensionElement;
025import org.jivesoftware.smack.packet.Message;
026import org.jivesoftware.smack.util.StringUtils;
027import org.jivesoftware.smack.util.XmlStringBuilder;
028import org.jivesoftware.smackx.spoiler.SpoilerManager;
029
030public class SpoilerElement implements ExtensionElement {
031
032    public static final String ELEMENT = "spoiler";
033    public static final String NAMESPACE = SpoilerManager.NAMESPACE_0;
034
035    public static final SpoilerElement EMPTY = new SpoilerElement(null, null);
036
037    private final String hint;
038    private final String language;
039
040    /**
041     * Create a new SpoilerElement with a hint about a content and a language attribute.
042     *
043     * @param language language of the hint.
044     * @param hint hint about the content.
045     */
046    public SpoilerElement(String language, String hint) {
047        if (StringUtils.isNotEmpty(language) && StringUtils.isNullOrEmpty(hint)) {
048            throw new IllegalArgumentException("Hint cannot be null or empty if language is not empty.");
049        }
050        this.language = language;
051        this.hint = hint;
052    }
053
054    /**
055     * Return the hint text of the spoiler.
056     * May be null.
057     *
058     * @return hint text
059     */
060    public String getHint() {
061        return hint;
062    }
063
064    /**
065     * Add a SpoilerElement to a message.
066     *
067     * @param message message to add the Spoiler to.
068     */
069    public static void addSpoiler(Message message) {
070        message.addExtension(SpoilerElement.EMPTY);
071    }
072
073    /**
074     * Add a SpoilerElement with a hint to a message.
075     *
076     * @param message Message to add the Spoiler to.
077     * @param hint Hint about the Spoilers content.
078     */
079    public static void addSpoiler(Message message, String hint) {
080        message.addExtension(new SpoilerElement(null, hint));
081    }
082
083    /**
084     * Add a SpoilerElement with a hint in a certain language to a message.
085     *
086     * @param message Message to add the Spoiler to.
087     * @param lang language of the Spoiler hint.
088     * @param hint hint.
089     */
090    public static void addSpoiler(Message message, String lang, String hint) {
091        message.addExtension(new SpoilerElement(lang, hint));
092    }
093
094
095    /**
096     * Returns true, if the message has at least one spoiler element.
097     *
098     * @param message message
099     * @return true if message has spoiler extension
100     */
101    public static boolean containsSpoiler(Message message) {
102        return message.hasExtension(SpoilerElement.ELEMENT, NAMESPACE);
103    }
104
105    /**
106     * Return a map of all spoilers contained in a message.
107     * The map uses the language of a spoiler as key.
108     * If a spoiler has no language attribute, its key will be an empty String.
109     *
110     * @param message message
111     * @return map of spoilers
112     */
113    public static Map<String, String> getSpoilers(Message message) {
114        if (!containsSpoiler(message)) {
115            return Collections.emptyMap();
116        }
117
118        List<ExtensionElement> spoilers = message.getExtensions(SpoilerElement.ELEMENT, NAMESPACE);
119        Map<String, String> map = new HashMap<>();
120
121        for (ExtensionElement e : spoilers) {
122            SpoilerElement s = (SpoilerElement) e;
123            if (s.getLanguage() == null || s.getLanguage().equals("")) {
124                map.put("", s.getHint());
125            } else {
126                map.put(s.getLanguage(), s.getHint());
127            }
128        }
129
130        return map;
131    }
132
133    /**
134     * Return the language of the hint.
135     * May be null.
136     *
137     * @return language of hint text
138     */
139    public String getLanguage() {
140        return language;
141    }
142
143    @Override
144    public String getNamespace() {
145        return NAMESPACE;
146    }
147
148    @Override
149    public String getElementName() {
150        return ELEMENT;
151    }
152
153    @Override
154    public CharSequence toXML(String enclosingNamespace) {
155        XmlStringBuilder xml = new XmlStringBuilder(this);
156        xml.optXmlLangAttribute(getLanguage());
157        if (getHint() == null) {
158            xml.closeEmptyElement();
159        } else {
160            xml.rightAngleBracket();
161            xml.append(getHint());
162            xml.closeElement(this);
163        }
164        return xml;
165    }
166}