001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (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 *     <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
016 *
017 * $Id: LayoutDescriptor.java 28478 2008-01-04 12:53:58Z sfermigier $
018 */
019
020package org.nuxeo.ecm.platform.forms.layout.descriptors;
021
022import java.io.Serializable;
023import java.util.ArrayList;
024import java.util.HashMap;
025import java.util.List;
026import java.util.Map;
027
028import org.nuxeo.common.xmap.annotation.XNode;
029import org.nuxeo.common.xmap.annotation.XNodeList;
030import org.nuxeo.common.xmap.annotation.XNodeMap;
031import org.nuxeo.common.xmap.annotation.XObject;
032import org.nuxeo.ecm.platform.forms.layout.api.BuiltinModes;
033import org.nuxeo.ecm.platform.forms.layout.api.LayoutDefinition;
034import org.nuxeo.ecm.platform.forms.layout.api.LayoutRowDefinition;
035import org.nuxeo.ecm.platform.forms.layout.api.RenderingInfo;
036import org.nuxeo.ecm.platform.forms.layout.api.WidgetDefinition;
037import org.nuxeo.ecm.platform.forms.layout.api.impl.LayoutDefinitionImpl;
038
039/**
040 * Layout definition descriptor.
041 *
042 * @author <a href="mailto:at@nuxeo.com">Anahide Tchertchian</a>
043 */
044@XObject("layout")
045public class LayoutDescriptor {
046
047    @XNode("@name")
048    String name;
049
050    /**
051     * @since 6.0
052     */
053    @XNode("@type")
054    String type;
055
056    /**
057     * @since 6.0
058     */
059    @XNode("@typeCategory")
060    String typeCategory;
061
062    @XNodeMap(value = "templates/template", key = "@mode", type = HashMap.class, componentType = String.class)
063    Map<String, String> templates = new HashMap<String, String>();
064
065    @XNodeList(value = "rows/row", type = LayoutRowDescriptor[].class, componentType = LayoutRowDescriptor.class)
066    LayoutRowDescriptor[] rows = new LayoutRowDescriptor[0];
067
068    @XNodeList(value = "columns/column", type = LayoutRowDescriptor[].class, componentType = LayoutRowDescriptor.class)
069    LayoutRowDescriptor[] rowsAsColumns = new LayoutRowDescriptor[0];
070
071    @XNodeMap(value = "widget", key = "@name", type = HashMap.class, componentType = WidgetDescriptor.class)
072    Map<String, WidgetDescriptor> widgets = new HashMap<String, WidgetDescriptor>();
073
074    @XNodeMap(value = "properties", key = "@mode", type = HashMap.class, componentType = PropertiesDescriptor.class)
075    Map<String, PropertiesDescriptor> properties = new HashMap<String, PropertiesDescriptor>();
076
077    @XNodeMap(value = "renderingInfos", key = "@mode", type = HashMap.class, componentType = RenderingInfosDescriptor.class)
078    Map<String, RenderingInfosDescriptor> renderingInfos = new HashMap<String, RenderingInfosDescriptor>();
079
080    @XNodeList(value = "categories/category", type = String[].class, componentType = String.class)
081    String[] categories = new String[0];
082
083    /**
084     * @since 6.0
085     */
086    @XNodeList(value = "aliases/alias", type = ArrayList.class, componentType = String.class)
087    List<String> aliases;
088
089    Integer columns;
090
091    public String getName() {
092        return name;
093    }
094
095    public String getType() {
096        return type;
097    }
098
099    public String getTypeCategory() {
100        return typeCategory;
101    }
102
103    public String getTemplate(String mode) {
104        String template = templates.get(mode);
105        if (template == null) {
106            template = templates.get(BuiltinModes.ANY);
107        }
108        return template;
109    }
110
111    public Map<String, String> getTemplates() {
112        return templates;
113    }
114
115    protected LayoutRowDefinition[] getDefinitions(LayoutRowDescriptor[] rows) {
116        LayoutRowDefinition[] crows = null;
117        if (rows != null) {
118            crows = new LayoutRowDefinition[rows.length];
119            for (int i = 0; i < rows.length; i++) {
120                crows[i] = rows[i].getLayoutRowDefinition();
121            }
122        }
123        return crows;
124    }
125
126    public LayoutRowDefinition[] getRows() {
127        // check if columns tags are used instead of rows, they act as aliases.
128        if (rowsAsColumns != null && rowsAsColumns.length > 0) {
129            return getDefinitions(rowsAsColumns);
130        }
131        return getDefinitions(rows);
132    }
133
134    public int getColumns() {
135        if (columns == null) {
136            // compute it
137            columns = Integer.valueOf(0);
138            LayoutRowDefinition[] rows = getRows();
139            for (LayoutRowDefinition def : rows) {
140                int current = def.getWidgetReferences().length;
141                if (current > columns.intValue()) {
142                    columns = Integer.valueOf(current);
143                }
144            }
145        }
146        return columns.intValue();
147    }
148
149    protected WidgetDefinition getWidgetDefinition(WidgetDescriptor desc) {
150        if (desc == null) {
151            return null;
152        }
153        return desc.getWidgetDefinition();
154    }
155
156    public WidgetDefinition getWidgetDefinition(String name) {
157        return getWidgetDefinition(widgets.get(name));
158    }
159
160    public Map<String, Serializable> getProperties(String layoutMode) {
161        return WidgetDescriptor.getProperties(properties, layoutMode);
162    }
163
164    public Map<String, Map<String, Serializable>> getProperties() {
165        return WidgetDescriptor.getProperties(properties);
166    }
167
168    /**
169     * Returns the categories for this layout, so that it can be stored in the corresponding registries.
170     *
171     * @since 5.5
172     */
173    public String[] getCategories() {
174        return categories;
175    }
176
177    /**
178     * @since 6.0
179     */
180    public List<String> getAliases() {
181        return aliases;
182    }
183
184    public LayoutDefinition getLayoutDefinition() {
185        Map<String, String> ctemplates = null;
186        if (templates != null) {
187            ctemplates = new HashMap<String, String>();
188            ctemplates.putAll(templates);
189        }
190        LayoutRowDefinition[] crows = getRows();
191        Map<String, WidgetDefinition> cwidgets = null;
192        if (widgets != null) {
193            cwidgets = new HashMap<String, WidgetDefinition>();
194            for (Map.Entry<String, WidgetDescriptor> entry : widgets.entrySet()) {
195                WidgetDescriptor w = entry.getValue();
196                cwidgets.put(entry.getKey(), getWidgetDefinition(w));
197            }
198        }
199        Map<String, List<RenderingInfo>> crenderingInfos = null;
200        if (renderingInfos != null) {
201            crenderingInfos = new HashMap<String, List<RenderingInfo>>();
202            for (Map.Entry<String, RenderingInfosDescriptor> item : renderingInfos.entrySet()) {
203                RenderingInfosDescriptor infos = item.getValue();
204                List<RenderingInfo> clonedInfos = null;
205                if (infos != null) {
206                    clonedInfos = new ArrayList<RenderingInfo>();
207                    for (RenderingInfoDescriptor info : infos.getRenderingInfos()) {
208                        clonedInfos.add(info.getRenderingInfo());
209                    }
210                }
211                crenderingInfos.put(item.getKey(), clonedInfos);
212            }
213        }
214        LayoutDefinitionImpl clone = new LayoutDefinitionImpl(name, getProperties(), ctemplates, crows, cwidgets);
215        clone.setRenderingInfos(crenderingInfos);
216        clone.setType(getType());
217        clone.setTypeCategory(getTypeCategory());
218        if (aliases != null) {
219            clone.setAliases(new ArrayList<String>(aliases));
220        }
221        return clone;
222    }
223}