1/**
2 * $RCSfile$
3 * $Revision$
4 * $Date$
5 *
6 * Copyright 2003-2007 Jive Software.
7 *
8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21package org.jivesoftware.smackx.packet;
22
23import org.jivesoftware.smack.packet.PacketExtension;
24
25import java.util.ArrayList;
26import java.util.Collections;
27import java.util.Iterator;
28import java.util.List;
29
30/**
31 * An XHTML sub-packet, which is used by XMPP clients to exchange formatted text. The XHTML
32 * extension is only a subset of XHTML 1.0.<p>
33 *
34 * The following link summarizes the requirements of XHTML IM:
35 * <a href="http://www.jabber.org/jeps/jep-0071.html#sect-id2598018">Valid tags</a>.<p>
36 *
37 * Warning: this is an non-standard protocol documented by
38 * <a href="http://www.jabber.org/jeps/jep-0071.html">JEP-71</a>. Because this is a
39 * non-standard protocol, it is subject to change.
40 *
41 * @author Gaston Dombiak
42 */
43public class XHTMLExtension implements PacketExtension {
44
45    private List<String> bodies = new ArrayList<String>();
46
47    /**
48    * Returns the XML element name of the extension sub-packet root element.
49    * Always returns "html"
50    *
51    * @return the XML element name of the packet extension.
52    */
53    public String getElementName() {
54        return "html";
55    }
56
57    /**
58     * Returns the XML namespace of the extension sub-packet root element.
59     * According the specification the namespace is always "http://jabber.org/protocol/xhtml-im"
60     *
61     * @return the XML namespace of the packet extension.
62     */
63    public String getNamespace() {
64        return "http://jabber.org/protocol/xhtml-im";
65    }
66
67    /**
68     * Returns the XML representation of a XHTML extension according the specification.
69     *
70     * Usually the XML representation will be inside of a Message XML representation like
71     * in the following example:
72     * <pre>
73     * &lt;message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack"&gt;
74     *     &lt;subject&gt;Any subject you want&lt;/subject&gt;
75     *     &lt;body&gt;This message contains something interesting.&lt;/body&gt;
76     *     &lt;html xmlns="http://jabber.org/protocol/xhtml-im"&gt;
77     *         &lt;body&gt;&lt;p style='font-size:large'&gt;This message contains something &lt;em&gt;interesting&lt;/em&gt;.&lt;/p&gt;&lt;/body&gt;
78     *     &lt;/html&gt;
79     * &lt;/message&gt;
80     * </pre>
81     *
82     */
83    public String toXML() {
84        StringBuilder buf = new StringBuilder();
85        buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
86            "\">");
87        // Loop through all the bodies and append them to the string buffer
88        for (Iterator<String> i = getBodies(); i.hasNext();) {
89            buf.append(i.next());
90        }
91        buf.append("</").append(getElementName()).append(">");
92        return buf.toString();
93    }
94
95    /**
96     * Returns an Iterator for the bodies in the packet.
97     *
98     * @return an Iterator for the bodies in the packet.
99     */
100    public Iterator<String> getBodies() {
101        synchronized (bodies) {
102            return Collections.unmodifiableList(new ArrayList<String>(bodies)).iterator();
103        }
104    }
105
106    /**
107     * Adds a body to the packet.
108     *
109     * @param body the body to add.
110     */
111    public void addBody(String body) {
112        synchronized (bodies) {
113            bodies.add(body);
114        }
115    }
116
117    /**
118     * Returns a count of the bodies in the XHTML packet.
119     *
120     * @return the number of bodies in the XHTML packet.
121     */
122    public int getBodiesCount() {
123        return bodies.size();
124    }
125
126}
127