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