001/**
002 *
003 * Copyright 2013-2014 Georg Lukas, 2020 Florian Schmaus
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.carbons.packet;
018
019import org.jivesoftware.smack.packet.ExtensionElement;
020import org.jivesoftware.smack.packet.Message;
021import org.jivesoftware.smack.packet.MessageBuilder;
022import org.jivesoftware.smack.util.XmlStringBuilder;
023
024import org.jivesoftware.smackx.forward.packet.Forwarded;
025
026/**
027 * Stanza extension for XEP-0280: Message Carbons. The extension
028 * <a href="http://xmpp.org/extensions/xep-0280.html">XEP-0280</a> is
029 * meant to synchronize a message flow to multiple presences of a user.
030 *
031 * <p>
032 * It accomplishes this by wrapping a {@link Forwarded} stanza in a <b>sent</b>
033 * or <b>received</b> element
034 *
035 * @author Georg Lukas
036 */
037public class CarbonExtension implements ExtensionElement {
038    public static final String NAMESPACE = Carbon.NAMESPACE;
039
040    private final Direction dir;
041    private final Forwarded<Message> fwd;
042
043    /**
044     * Construct a Carbon message extension.
045     *
046     * @param dir Determines if the carbon is being sent/received
047     * @param fwd The forwarded message.
048     */
049    public CarbonExtension(Direction dir, Forwarded<Message> fwd) {
050        this.dir = dir;
051        this.fwd = fwd;
052    }
053
054    /**
055     * Get the direction (sent or received) of the carbon.
056     *
057     * @return the {@link Direction} of the carbon.
058     */
059    public Direction getDirection() {
060        return dir;
061    }
062
063    /**
064     * Get the forwarded packet.
065     *
066     * @return the {@link Forwarded} message contained in this Carbon.
067     */
068    public Forwarded<Message> getForwarded() {
069        return fwd;
070    }
071
072    @Override
073    public String getElementName() {
074        return dir.name();
075    }
076
077    @Override
078    public String getNamespace() {
079        return NAMESPACE;
080    }
081
082    @Override
083    public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
084        XmlStringBuilder xml = new XmlStringBuilder(this);
085        xml.rightAngleBracket();
086        xml.append(fwd.toXML());
087        xml.closeElement(this);
088        return xml;
089    }
090
091    /**
092     * Obtain a Carbon from a message, if available.
093     * <p>
094     * Only {@link Message} instances can contain a Carbon extensions.
095     * </p>
096     *
097     * @param msg Message object to check for carbons
098     *
099     * @return a Carbon if available, null otherwise.
100     * @deprecated use {@link #from(Message)} instead
101     */
102    @Deprecated
103    public static CarbonExtension getFrom(Message msg) {
104        return from(msg);
105    }
106
107    /**
108     * Obtain a Carbon from a message, if available.
109     * <p>
110     * Only {@link Message} instances can contain a Carbon extensions.
111     * </p>
112     *
113     * @param msg Message object to check for carbons
114     *
115     * @return a Carbon if available, null otherwise.
116     */
117    public static CarbonExtension from(Message msg) {
118        CarbonExtension cc = (CarbonExtension) msg.getExtensionElement(Direction.received.name(), NAMESPACE);
119        if (cc == null)
120            cc = (CarbonExtension) msg.getExtensionElement(Direction.sent.name(), NAMESPACE);
121        return cc;
122    }
123
124    /**
125     * Defines the direction of a {@link CarbonExtension} message.
126     */
127    public enum Direction {
128        received,
129        sent
130    }
131
132    /**
133     * Stanza extension indicating that a message may not be carbon-copied.  Adding this
134     * extension to any message will disallow that message from being copied.
135     */
136    public static final class Private implements ExtensionElement {
137        public static final Private INSTANCE = new Private();
138        public static final String ELEMENT = "private";
139
140        private Private() {
141        }
142
143        @Override
144        public String getElementName() {
145            return ELEMENT;
146        }
147
148        @Override
149        public String getNamespace() {
150            return NAMESPACE;
151        }
152
153        @Override
154        public String toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
155            return "<" + ELEMENT + " xmlns='" + NAMESPACE + "'/>";
156        }
157
158        /**
159         * Marks a message "private", so that it will not be carbon-copied, by adding private packet
160         * extension to the message.
161         *
162         * @param messageBuilder the message to add the private extension to
163         */
164        public static void addTo(MessageBuilder messageBuilder) {
165            messageBuilder.addExtension(INSTANCE);
166        }
167
168        /**
169         * Marks a message "private", so that it will not be carbon-copied, by adding private packet
170         * extension to the message.
171         *
172         * @param message the message to add the private extension to
173         * @deprecated use {@link #addTo(MessageBuilder)} instead.
174         */
175        // TODO: Remove in Smack 4.6
176        @Deprecated
177        public static void addTo(Message message) {
178            message.addExtension(INSTANCE);
179        }
180    }
181}