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