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;
028
029import org.jivesoftware.smackx.spoiler.SpoilerManager;
030
031public class SpoilerElement implements ExtensionElement {
032
033    public static final String ELEMENT = "spoiler";
034    public static final String NAMESPACE = SpoilerManager.NAMESPACE_0;
035
036    public static final SpoilerElement EMPTY = new SpoilerElement(null, null);
037
038    private final String hint;
039    private final String language;
040
041    /**
042     * Create a new SpoilerElement with a hint about a content and a language attribute.
043     *
044     * @param language language of the hint.
045     * @param hint hint about the content.
046     */
047    public SpoilerElement(String language, String hint) {
048        if (StringUtils.isNotEmpty(language) && StringUtils.isNullOrEmpty(hint)) {
049            throw new IllegalArgumentException("Hint cannot be null or empty if language is not empty.");
050        }
051        this.language = language;
052        this.hint = hint;
053    }
054
055    /**
056     * Return the hint text of the spoiler.
057     * May be null.
058     *
059     * @return hint text
060     */
061    public String getHint() {
062        return hint;
063    }
064
065    /**
066     * Add a SpoilerElement to a message.
067     *
068     * @param message message to add the Spoiler to.
069     */
070    public static void addSpoiler(Message message) {
071        message.addExtension(SpoilerElement.EMPTY);
072    }
073
074    /**
075     * Add a SpoilerElement with a hint to a message.
076     *
077     * @param message Message to add the Spoiler to.
078     * @param hint Hint about the Spoilers content.
079     */
080    public static void addSpoiler(Message message, String hint) {
081        message.addExtension(new SpoilerElement(null, hint));
082    }
083
084    /**
085     * Add a SpoilerElement with a hint in a certain language to a message.
086     *
087     * @param message Message to add the Spoiler to.
088     * @param lang language of the Spoiler hint.
089     * @param hint hint.
090     */
091    public static void addSpoiler(Message message, String lang, String hint) {
092        message.addExtension(new SpoilerElement(lang, hint));
093    }
094
095
096    /**
097     * Returns true, if the message has at least one spoiler element.
098     *
099     * @param message message
100     * @return true if message has spoiler extension
101     */
102    public static boolean containsSpoiler(Message message) {
103        return message.hasExtension(SpoilerElement.ELEMENT, NAMESPACE);
104    }
105
106    /**
107     * Return a map of all spoilers contained in a message.
108     * The map uses the language of a spoiler as key.
109     * If a spoiler has no language attribute, its key will be an empty String.
110     *
111     * @param message message
112     * @return map of spoilers
113     */
114    public static Map<String, String> getSpoilers(Message message) {
115        if (!containsSpoiler(message)) {
116            return Collections.emptyMap();
117        }
118
119        List<ExtensionElement> spoilers = message.getExtensions(SpoilerElement.ELEMENT, NAMESPACE);
120        Map<String, String> map = new HashMap<>();
121
122        for (ExtensionElement e : spoilers) {
123            SpoilerElement s = (SpoilerElement) e;
124            if (s.getLanguage() == null || s.getLanguage().equals("")) {
125                map.put("", s.getHint());
126            } else {
127                map.put(s.getLanguage(), s.getHint());
128            }
129        }
130
131        return map;
132    }
133
134    @Override
135    public String getLanguage() {
136        return language;
137    }
138
139    @Override
140    public String getNamespace() {
141        return NAMESPACE;
142    }
143
144    @Override
145    public String getElementName() {
146        return ELEMENT;
147    }
148
149    @Override
150    public CharSequence toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
151        XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
152        if (getHint() == null) {
153            xml.closeEmptyElement();
154        } else {
155            xml.rightAngleBracket();
156            xml.append(getHint());
157            xml.closeElement(this);
158        }
159        return xml;
160    }
161}