001/*
002 * (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.platform.forms.layout.descriptors;
018
019import java.io.IOException;
020import java.io.Serializable;
021import java.util.ArrayList;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.apache.xml.serialize.OutputFormat;
029import org.nuxeo.common.xmap.DOMSerializer;
030import org.nuxeo.common.xmap.annotation.XContent;
031import org.nuxeo.common.xmap.annotation.XNode;
032import org.nuxeo.common.xmap.annotation.XNodeList;
033import org.nuxeo.common.xmap.annotation.XNodeMap;
034import org.nuxeo.common.xmap.annotation.XObject;
035import org.nuxeo.ecm.platform.forms.layout.api.FieldDefinition;
036import org.nuxeo.ecm.platform.forms.layout.api.LayoutDefinition;
037import org.nuxeo.ecm.platform.forms.layout.api.WidgetTypeConfiguration;
038import org.nuxeo.ecm.platform.forms.layout.api.impl.WidgetTypeConfigurationImpl;
039import org.w3c.dom.DocumentFragment;
040
041/**
042 * Descriptor for a widget type configuration
043 *
044 * @author Anahide Tchertchian
045 * @since 5.4
046 */
047@XObject("configuration")
048@SuppressWarnings("deprecation")
049public class WidgetTypeConfigurationDescriptor {
050
051    private static final Log log = LogFactory.getLog(WidgetTypeConfigurationDescriptor.class);
052
053    @XNode("sinceVersion")
054    String sinceVersion;
055
056    /**
057     * @since 5.6
058     */
059    @XNode("deprecatedVersion")
060    String deprecatedVersion;
061
062    @XNode("title")
063    String title;
064
065    // retrieve HTML tags => introspect DOM on setter
066    String description;
067
068    @XNode("demo@id")
069    String demoId;
070
071    @XNode("demo@previewEnabled")
072    boolean demoPreviewEnabled = false;
073
074    @XNodeList(value = "supportedModes/mode", type = ArrayList.class, componentType = String.class)
075    List<String> supportedModes;
076
077    @XNode("acceptingSubWidgets")
078    boolean acceptingSubWidgets = false;
079
080    /**
081     * @since 5.6
082     */
083    @XNode("handlingLabels")
084    boolean handlingLabels = false;
085
086    /**
087     * List of supported controls (controls checked on subwidgets configuration).
088     *
089     * @since 5.9.1
090     */
091    @XNodeList(value = "supportedControls/control", type = ArrayList.class, componentType = String.class)
092    List<String> supportedControls;
093
094    @XNode("fields/list")
095    boolean list = false;
096
097    @XNode("fields/complex")
098    boolean complex = false;
099
100    @XNode("containingForm")
101    boolean containingForm = false;
102
103    @XNodeList(value = "fields/supportedTypes/type", type = ArrayList.class, componentType = String.class)
104    List<String> supportedFieldTypes;
105
106    @XNodeList(value = "fields/defaultTypes/type", type = ArrayList.class, componentType = String.class)
107    List<String> defaultFieldTypes;
108
109    @XNodeList(value = "fields/defaultConfiguration/field", type = ArrayList.class, componentType = FieldDescriptor.class)
110    List<FieldDescriptor> defaultFieldDefinitions;
111
112    /**
113     * Layouts for accepted field mappings.
114     *
115     * @since 5.7.3
116     */
117    @XNodeMap(value = "fields/layouts", key = "@mode", type = HashMap.class, componentType = LayoutDescriptors.class)
118    Map<String, LayoutDescriptors> fieldLayouts;
119
120    @XNodeList(value = "categories/category", type = ArrayList.class, componentType = String.class)
121    List<String> categories;
122
123    @XNodeMap(value = "properties/layouts", key = "@mode", type = HashMap.class, componentType = LayoutDescriptors.class)
124    Map<String, LayoutDescriptors> propertyLayouts;
125
126    /**
127     * @since 5.7.3
128     */
129    @XNodeMap(value = "properties/defaultValues", key = "@mode", type = HashMap.class, componentType = PropertiesDescriptor.class)
130    Map<String, PropertiesDescriptor> defaultPropertyValues;
131
132    /**
133     * @since 5.7.3
134     */
135    @XNodeMap(value = "controls/defaultValues", key = "@mode", type = HashMap.class, componentType = ControlsDescriptor.class)
136    Map<String, ControlsDescriptor> defaultControlValues;
137
138    Map<String, Serializable> properties;
139
140    public List<String> getCategories() {
141        return categories;
142    }
143
144    public String getDescription() {
145        return description;
146    }
147
148    @XContent("description")
149    public void setDescription(DocumentFragment descriptionDOM) {
150        try {
151            OutputFormat of = new OutputFormat();
152            of.setOmitXMLDeclaration(true);
153            this.description = DOMSerializer.toString(descriptionDOM, of).trim();
154        } catch (IOException e) {
155            log.error(e, e);
156        }
157    }
158
159    public String getTitle() {
160        return title;
161    }
162
163    public String getDemoId() {
164        return demoId;
165    }
166
167    public boolean isDemoPreviewEnabled() {
168        return demoPreviewEnabled;
169    }
170
171    public boolean isAcceptingSubWidgets() {
172        return acceptingSubWidgets;
173    }
174
175    /**
176     * @since 5.6
177     */
178    public boolean isHandlingLabels() {
179        return handlingLabels;
180    }
181
182    /**
183     * @since 5.9.1
184     */
185    public List<String> getSupportedControls() {
186        return supportedControls;
187    }
188
189    public boolean isComplex() {
190        return complex;
191    }
192
193    public boolean isList() {
194        return list;
195    }
196
197    public boolean isContainingForm() {
198        return containingForm;
199    }
200
201    public List<String> getDefaultFieldTypes() {
202        return defaultFieldTypes;
203    }
204
205    public List<String> getSupportedFieldTypes() {
206        return supportedFieldTypes;
207    }
208
209    public List<FieldDefinition> getDefaultFieldDefinitions() {
210        if (defaultFieldDefinitions == null) {
211            return null;
212        }
213        List<FieldDefinition> res = new ArrayList<FieldDefinition>();
214        for (int i = 0; i < defaultFieldDefinitions.size(); i++) {
215            res.add(defaultFieldDefinitions.get(i).getFieldDefinition());
216        }
217        return res;
218    }
219
220    public Map<String, Serializable> getConfProperties() {
221        return properties;
222    }
223
224    public Serializable getConfProperty(String propName) {
225        if (properties == null) {
226            return null;
227        }
228        return properties.get(propName);
229    }
230
231    @XNode("confProperties")
232    public void setConfProperties(PropertiesDescriptor propsDesc) {
233        properties = propsDesc.getProperties();
234    }
235
236    protected List<LayoutDefinition> getLayouts(Map<String, LayoutDescriptors> descs, String mode, String additionalMode) {
237        if (descs != null) {
238            List<LayoutDefinition> res = new ArrayList<LayoutDefinition>();
239            if (additionalMode != null) {
240                LayoutDescriptors defaultLayouts = descs.get(additionalMode);
241                if (defaultLayouts != null) {
242                    List<LayoutDefinition> defaultLayoutsList = defaultLayouts.getLayouts();
243                    if (defaultLayoutsList != null) {
244                        res.addAll(defaultLayoutsList);
245                    }
246                }
247            }
248            LayoutDescriptors modeLayouts = descs.get(mode);
249            if (modeLayouts != null) {
250                List<LayoutDefinition> modeLayoutsList = modeLayouts.getLayouts();
251                if (modeLayoutsList != null) {
252                    res.addAll(modeLayoutsList);
253                }
254            }
255            return res;
256        }
257        return null;
258    }
259
260    protected Map<String, List<LayoutDefinition>> getLayouts(Map<String, LayoutDescriptors> descs) {
261        if (descs != null) {
262            Map<String, List<LayoutDefinition>> res = new HashMap<String, List<LayoutDefinition>>();
263            for (Map.Entry<String, LayoutDescriptors> entry : descs.entrySet()) {
264                res.put(entry.getKey(), entry.getValue().getLayouts());
265            }
266            return res;
267        }
268        return null;
269    }
270
271    public List<LayoutDefinition> getPropertyLayouts(String mode, String additionalMode) {
272        return getLayouts(propertyLayouts, mode, additionalMode);
273    }
274
275    public Map<String, List<LayoutDefinition>> getPropertyLayouts() {
276        return getLayouts(propertyLayouts);
277    }
278
279    public List<LayoutDefinition> getFieldLayouts(String mode, String additionalMode) {
280        return getLayouts(fieldLayouts, mode, additionalMode);
281    }
282
283    public Map<String, List<LayoutDefinition>> getFieldLayouts() {
284        return getLayouts(fieldLayouts);
285    }
286
287    public Map<String, Map<String, Serializable>> getDefaultPropertyValues() {
288        if (defaultPropertyValues != null) {
289            Map<String, Map<String, Serializable>> res = new HashMap<String, Map<String, Serializable>>();
290            for (Map.Entry<String, PropertiesDescriptor> entry : defaultPropertyValues.entrySet()) {
291                res.put(entry.getKey(), entry.getValue().getProperties());
292            }
293            return res;
294        }
295        return null;
296    }
297
298    public Map<String, Map<String, Serializable>> getDefaultControlValues() {
299        if (defaultControlValues != null) {
300            Map<String, Map<String, Serializable>> res = new HashMap<String, Map<String, Serializable>>();
301            for (Map.Entry<String, ControlsDescriptor> entry : defaultControlValues.entrySet()) {
302                res.put(entry.getKey(), entry.getValue().getControls());
303            }
304            return res;
305        }
306        return null;
307    }
308
309    public String getSinceVersion() {
310        return sinceVersion;
311    }
312
313    /**
314     * @since 5.6
315     */
316    public String getDeprecatedVersion() {
317        return deprecatedVersion;
318    }
319
320    public List<String> getSupportedModes() {
321        return supportedModes;
322    }
323
324    public WidgetTypeConfiguration getWidgetTypeConfiguration() {
325        WidgetTypeConfigurationImpl res = new WidgetTypeConfigurationImpl();
326        res.setSinceVersion(getSinceVersion());
327        res.setDeprecatedVersion(getDeprecatedVersion());
328        res.setTitle(getTitle());
329        res.setDescription(getDescription());
330        res.setDemoId(getDemoId());
331        res.setDemoPreviewEnabled(isDemoPreviewEnabled());
332        res.setProperties(getConfProperties());
333        res.setSupportedModes(getSupportedModes());
334        res.setAcceptingSubWidgets(isAcceptingSubWidgets());
335        res.setHandlingLabels(isHandlingLabels());
336        res.setList(isList());
337        res.setComplex(isComplex());
338        res.setContainingForm(isContainingForm());
339        res.setSupportedFieldTypes(getSupportedFieldTypes());
340        res.setDefaultFieldTypes(getDefaultFieldTypes());
341        res.setDefaultFieldDefinitions(getDefaultFieldDefinitions());
342        res.setCategories(getCategories());
343        res.setPropertyLayouts(getPropertyLayouts());
344        res.setDefaultPropertyValues(getDefaultPropertyValues());
345        res.setDefaultControlValues(getDefaultControlValues());
346        res.setFieldLayouts(getFieldLayouts());
347        res.setSupportedControls(getSupportedControls());
348        return res;
349    }
350}