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