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