001/**
002 *
003 * Copyright 2014 Anno van Vliet 
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.xdatalayout.packet;
018
019import java.util.ArrayList;
020import java.util.List;
021
022import org.jivesoftware.smack.packet.ExtensionElement;
023import org.jivesoftware.smack.packet.NamedElement;
024import org.jivesoftware.smack.util.XmlStringBuilder;
025
026/**
027 * DataLayout Extension according to XEP-0141: Data Forms Layout.
028 * Defines a backwards-compatible extension to the XMPP Data Forms protocol that 
029 * enables an application to specify form layouts, including the layout of 
030 * form fields, sections within pages, and subsections within sections.
031 *
032 * @author Anno van Vliet
033 */
034public class DataLayout implements ExtensionElement {
035
036    public static final String ELEMENT = "page";
037    public static final String NAMESPACE = "http://jabber.org/protocol/xdata-layout";
038
039    private final List<DataFormLayoutElement> pageLayout = new ArrayList<>();
040    private final String label;
041
042    /**
043     * Data layout constructor.
044     * @param label
045     */
046    public DataLayout(String label) {
047        this.label = label;
048    }
049
050    /**
051     * Gets the value of the pageLayout property.
052     * <p>
053     * Objects of the following type(s) are allowed in the list: {@link String },
054     * {@link Section }, {@link Fieldref } and {@link Reportedref }
055     *
056     * @return list of DataFormLayoutElements.
057     */
058    public List<DataFormLayoutElement> getPageLayout() {
059        return this.pageLayout;
060    }
061
062    /**
063     * Gets the value of the label property.
064     * 
065     * @return possible object is {@link String }
066     */
067    public String getLabel() {
068        return label;
069    }
070
071    /*
072     * (non-Javadoc)
073     * @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
074     */
075    @Override
076    public String getElementName() {
077        return ELEMENT;
078    }
079
080    /*
081     * (non-Javadoc)
082     * @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
083     */
084    @Override
085    public String getNamespace() {
086        return NAMESPACE;
087    }
088
089    /*
090     * (non-Javadoc)
091     * @see org.jivesoftware.smack.packet.PacketExtension#toXML()
092     */
093    @Override
094    public XmlStringBuilder toXML() {
095        XmlStringBuilder buf = new XmlStringBuilder(this);
096        buf.optAttribute("label", getLabel());
097        buf.rightAngleBracket();
098
099        walkList(buf, getPageLayout());
100
101        buf.closeElement(this);
102
103        return buf;
104    }
105
106    /**
107     * @param buf
108     * @param pageLayout
109     */
110    private static void walkList(XmlStringBuilder buf, List<DataFormLayoutElement> pageLayout) {
111        for (DataFormLayoutElement object : pageLayout) {
112            buf.append(object.toXML());
113        }
114    }
115
116    public static class Fieldref implements DataFormLayoutElement{
117
118        public static final String ELEMENT = "fieldref";
119        private final String var;
120
121        /**
122         * Field ref constructor.
123         * @param var reference to a field
124         */
125        public Fieldref(String var) {
126            this.var = var;
127        }
128
129        @Override
130        public XmlStringBuilder toXML() {
131            XmlStringBuilder buf = new XmlStringBuilder(this);
132            buf.attribute("var", getVar());
133            buf.closeEmptyElement();
134            return buf;
135        }
136
137        /**
138         * Gets the value of the var property.
139         * 
140         * @return possible object is {@link String }
141         */
142        public String getVar() {
143            return var;
144        }
145
146        @Override
147        public String getElementName() {
148            return ELEMENT;
149        }
150
151    }
152
153    public static class Section implements DataFormLayoutElement{
154
155        public static final String ELEMENT = "section";
156        private final List<DataFormLayoutElement> sectionLayout = new ArrayList<>();
157        private final String label;
158
159        /**
160         * Section constructor.
161         * @param label
162         */
163        public Section(String label) {
164            this.label = label;
165        }
166
167        /**
168         * Gets the value of the sectionLayout property.
169         * <p>
170         * This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you
171         * make to the returned list will be present inside the object. This is why there is not a <CODE>set</CODE>
172         * method for the sectionLayout property.
173         * <p>
174         * For example, to add a new item, do as follows:
175         * 
176         * <pre>
177         * getSectionLayout().add(newItem);
178         * </pre>
179         * <p>
180         * Objects of the following type(s) are allowed in the list: {@link String },
181         * {@link Section }, {@link Fieldref } and {@link Reportedref }
182         *
183         * @return list of DataFormLayoutElements.
184         */
185        public List<DataFormLayoutElement> getSectionLayout() {
186            return this.sectionLayout;
187        }
188
189        @Override
190        public XmlStringBuilder toXML() {
191            XmlStringBuilder buf = new XmlStringBuilder(this);
192            buf.optAttribute("label", getLabel());
193            buf.rightAngleBracket();
194
195            walkList(buf, getSectionLayout());
196            buf.closeElement(ELEMENT);
197            return buf;
198        }
199
200        /**
201         * Gets the value of the label property.
202         * 
203         * @return possible object is {@link String }
204         */
205        public String getLabel() {
206            return label;
207        }
208
209        @Override
210        public String getElementName() {
211            return ELEMENT;
212        }
213
214    }
215
216    public static class Reportedref implements DataFormLayoutElement{
217
218        public static final String ELEMENT = "reportedref";
219
220        @Override
221        public XmlStringBuilder toXML() {
222            XmlStringBuilder buf = new XmlStringBuilder(this);
223            buf.closeEmptyElement();
224            return buf;
225        }
226
227        @Override
228        public String getElementName() {
229            return ELEMENT;
230        }
231
232    }
233
234    public static class Text implements DataFormLayoutElement{
235        public static final String ELEMENT = "text";
236        private final String text;
237
238        /**
239         * Text constructor.
240         * @param text reference to a field
241         */
242        public Text(String text) {
243            this.text = text;
244        }
245
246        @Override
247        public XmlStringBuilder toXML() {
248            XmlStringBuilder buf = new XmlStringBuilder();
249            buf.element(ELEMENT, getText());
250            return buf;
251        }
252
253        /**
254         * Gets the value of the var property.
255         * 
256         * @return possible object is {@link String }
257         */
258        public String getText() {
259            return text;
260        }
261
262        @Override
263        public String getElementName() {
264            return ELEMENT;
265        }
266
267    }
268
269    public interface DataFormLayoutElement extends NamedElement {
270    }
271
272}