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