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