001/**
002 *
003 * Copyright 2014 Andriy Tsykholyas
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.hoxt.packet;
018
019import javax.xml.namespace.QName;
020
021import org.jivesoftware.smack.packet.ExtensionElement;
022import org.jivesoftware.smack.packet.IQ;
023import org.jivesoftware.smack.packet.NamedElement;
024import org.jivesoftware.smack.util.Objects;
025import org.jivesoftware.smack.util.XmlStringBuilder;
026
027import org.jivesoftware.smackx.shim.packet.HeadersExtension;
028
029/**
030 * Abstract parent for Req and Resp IQ packets.
031 *
032 * @author Andriy Tsykholyas
033 * @see <a href="http://xmpp.org/extensions/xep-0332.html">XEP-0332: HTTP over XMPP transport</a>
034 */
035public abstract class AbstractHttpOverXmpp extends IQ {
036
037    public static final String NAMESPACE = "urn:xmpp:http";
038
039    private final HeadersExtension headers;
040    private final Data data;
041
042    private final String version;
043
044    protected AbstractHttpOverXmpp(String element, Builder<?, ?> builder) {
045        super(element, NAMESPACE);
046        this.headers = builder.headers;
047        this.data = builder.data;
048        this.version = Objects.requireNonNull(builder.version, "version must not be null");
049    }
050
051    @Override
052    protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
053        IQChildElementXmlStringBuilder builder = getIQHoxtChildElementBuilder(xml);
054        builder.optAppend(headers);
055        builder.optAppend(data);
056        return builder;
057    }
058
059    /**
060     * Returns start tag.
061     *
062     * @param xml builder.
063     * @return start tag
064     */
065    protected abstract IQChildElementXmlStringBuilder getIQHoxtChildElementBuilder(IQChildElementXmlStringBuilder xml);
066
067    /**
068     * Returns version attribute.
069     *
070     * @return version attribute
071     */
072    public String getVersion() {
073        return version;
074    }
075
076    /**
077     * Returns Headers element.
078     *
079     * @return Headers element
080     */
081    public HeadersExtension getHeaders() {
082        return headers;
083    }
084
085    /**
086     * Returns Data element.
087     *
088     * @return Data element
089     */
090    public Data getData() {
091        return data;
092    }
093
094    /**
095     * A builder for XMPP connection configurations.
096     * <p>
097     * See ConnectionConfiguration Builder for more details.
098     * </p>
099     *
100     * @param <B> the builder type parameter.
101     * @param <C> the resulting HttpOverXmpp IQ
102     */
103    public abstract static class Builder<B extends Builder<B, C>, C extends AbstractHttpOverXmpp> {
104
105        private HeadersExtension headers;
106        private Data data;
107
108        private String version = "1.1";
109
110        /**
111         * Sets Data element.
112         *
113         * @param data Headers element
114         *
115         * @return the builder
116         */
117        public B setData(Data data) {
118            this.data = data;
119            return getThis();
120        }
121
122        /**
123         * Sets Headers element.
124         *
125         * @param headers Headers element
126         *
127         * @return the builder
128         */
129        public B setHeaders(HeadersExtension headers) {
130            this.headers = headers;
131            return getThis();
132        }
133
134        /**
135         * Sets version attribute.
136         *
137         * @param version version attribute
138         *
139         * @return the builder
140         */
141        public B setVersion(String version) {
142            this.version = version;
143            return getThis();
144        }
145
146        public abstract C build();
147
148        protected abstract B getThis();
149    }
150
151    private abstract static class HoxExtensionElement implements ExtensionElement {
152        @Override
153        public final String getNamespace() {
154            return NAMESPACE;
155        }
156    }
157
158    /**
159     * Representation of Data element.
160     * <p>
161     * This class is immutable.
162     */
163    public static class Data extends HoxExtensionElement {
164
165        public static final String ELEMENT = "data";
166        public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
167
168        private final NamedElement child;
169
170        /**
171         * Creates Data element.
172         *
173         * @param child element nested by Data
174         */
175        public Data(NamedElement child) {
176            this.child = child;
177        }
178
179        /**
180         * Returns string containing xml representation of this object.
181         *
182         * @return xml representation of this object
183         */
184        @Override
185        public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
186            XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
187            xml.rightAngleBracket();
188            xml.append(child);
189            xml.closeElement(this);
190            return xml;
191        }
192
193        /**
194         * Returns element nested by Data.
195         *
196         * @return element nested by Data
197         */
198        public NamedElement getChild() {
199            return child;
200        }
201
202        @Override
203        public String getElementName() {
204            return ELEMENT;
205        }
206    }
207
208    /**
209     * Representation of Text element.
210     * <p>
211     * This class is immutable.
212     */
213    public static class Text extends HoxExtensionElement {
214
215        public static final String ELEMENT = "text";
216        public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
217
218        private final String text;
219
220        /**
221         * Creates this element.
222         *
223         * @param text value of text
224         */
225        public Text(String text) {
226            this.text = text;
227        }
228
229        @Override
230        public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
231            XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
232            xml.optTextChild(text, this);
233            return xml;
234        }
235
236        /**
237         * Returns text of this element.
238         *
239         * @return text TODO javadoc me please
240         */
241        public String getText() {
242            return text;
243        }
244
245        @Override
246        public String getElementName() {
247            return ELEMENT;
248        }
249    }
250
251    /**
252     * Representation of Base64 element.
253     * <p>
254     * This class is immutable.
255     */
256    public static class Base64 extends HoxExtensionElement {
257
258        public static final String ELEMENT = "base64";
259        public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
260
261        private final String text;
262
263        /**
264         * Creates this element.
265         *
266         * @param text value of text
267         */
268        public Base64(String text) {
269            this.text = text;
270        }
271
272        @Override
273        public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
274            XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
275            xml.optTextChild(text, this);
276            return xml;
277        }
278
279        /**
280         * Returns text of this element.
281         *
282         * @return text TODO javadoc me please
283         */
284        public String getText() {
285            return text;
286        }
287
288        @Override
289        public String getElementName() {
290            return ELEMENT;
291        }
292    }
293
294    /**
295     * Representation of Xml element.
296     * <p>
297     * This class is immutable.
298     */
299    public static class Xml extends HoxExtensionElement {
300
301        public static final String ELEMENT = "xml";
302        public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
303
304        private final String text;
305
306        /**
307         * Creates this element.builder.toString().
308         *
309         * @param text value of text
310         */
311        public Xml(String text) {
312            this.text = text;
313        }
314
315        @Override
316        public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
317            XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
318            xml.optTextChild(text, this);
319            return xml;
320        }
321
322        /**
323         * Returns text of this element.
324         *
325         * @return text TODO javadoc me please
326         */
327        public String getText() {
328            return text;
329        }
330
331        @Override
332        public String getElementName() {
333            return ELEMENT;
334        }
335    }
336
337    /**
338     * Representation of ChunkedBase64 element.
339     * <p>
340     * This class is immutable.
341     */
342    public static class ChunkedBase64 extends HoxExtensionElement {
343
344        public static final String ELEMENT = "chunkedBase64";
345        public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
346
347        private final String streamId;
348
349        /**
350         * Creates ChunkedBase86 element.
351         *
352         * @param streamId streamId attribute
353         */
354        public ChunkedBase64(String streamId) {
355            this.streamId = streamId;
356        }
357
358        @Override
359        public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
360            XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
361            xml.attribute("streamId", streamId);
362            xml.closeEmptyElement();
363            return xml;
364        }
365
366        /**
367         * Returns streamId attribute.
368         *
369         * @return streamId attribute
370         */
371        public String getStreamId() {
372            return streamId;
373        }
374
375        @Override
376        public String getElementName() {
377            return ELEMENT;
378        }
379    }
380
381    /**
382     * Representation of Ibb element.
383     * <p>
384     * This class is immutable.
385     */
386    public static class Ibb extends HoxExtensionElement {
387
388        public static final String ELEMENT = "ibb";
389        public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
390
391        private final String sid;
392
393        /**
394         * Creates Ibb element.
395         *
396         * @param sid sid attribute
397         */
398        public Ibb(String sid) {
399            this.sid = sid;
400        }
401
402        @Override
403        public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
404            XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
405            xml.attribute("sid", sid);
406            xml.closeEmptyElement();
407            return xml;
408        }
409
410        /**
411         * Returns sid attribute.
412         *
413         * @return sid attribute
414         */
415        public String getSid() {
416            return sid;
417        }
418
419        @Override
420        public String getElementName() {
421            return ELEMENT;
422        }
423    }
424}