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