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 *     Nuxeo - initial API and implementation
018 *
019 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
020 */
021
022package org.nuxeo.ecm.platform.types;
023
024import java.io.Serializable;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.HashMap;
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;
036
037@XObject("type")
038public class Type implements Serializable {
039
040    private static final long serialVersionUID = 1L;
041
042    public static final String[] EMPTY_ACTIONS = new String[0];
043
044    @XNode("@id")
045    protected String id;
046
047    @XNode("icon")
048    protected String icon;
049
050    @XNode("icon-expanded")
051    protected String iconExpanded;
052
053    @XNode("bigIcon")
054    protected String bigIcon;
055
056    @XNode("bigIcon-expanded")
057    protected String bigIconExpanded;
058
059    @XNode("label")
060    protected String label;
061
062    protected Type(String id) {
063        this.id = id;
064    }
065
066    public Type() {
067
068    }
069
070    protected Map<String, SubType> allowedSubTypes = new HashMap<>();
071
072    @XNodeList(value = "subtypes/type", type = ArrayList.class, componentType = SubType.class)
073    public void addSubType(List<SubType> subTypes) {
074        if (allowedSubTypes == null) {
075            allowedSubTypes = new HashMap<String, SubType>();
076        }
077
078        for (SubType currentSubType : subTypes) {
079            SubType subTypeToMerge = allowedSubTypes.get(currentSubType.name);
080            if (subTypeToMerge == null) {
081                allowedSubTypes.put(currentSubType.name, currentSubType);
082            } else {
083                List<String> currentSubTypeHidden = currentSubType.getHidden();
084                List<String> subTypeToMergeHidden = subTypeToMerge.getHidden();
085                for (String hidden : currentSubTypeHidden) {
086                    if (!subTypeToMergeHidden.contains(hidden)) {
087                        subTypeToMergeHidden.add(hidden);
088                    }
089                }
090            }
091        }
092    }
093
094    @XNodeList(value = "deniedSubtypes/type", type = String[].class, componentType = String.class)
095    protected String[] deniedSubTypes;
096
097    @XNode("default-view")
098    protected String defaultView;
099
100    @XNode("create-view")
101    protected String createView;
102
103    @XNode("edit-view")
104    protected String editView;
105
106    @XNode("description")
107    protected String description;
108
109    @XNode("category")
110    protected String category;
111
112    protected Map<String, TypeView> views;
113
114    @XNodeList(value = "actions/action", type = String[].class, componentType = String.class)
115    protected String[] actions;
116
117    @XNodeMap(value = "layouts", key = "@mode", type = HashMap.class, componentType = Layouts.class)
118    Map<String, Layouts> layouts;
119
120    @XNodeMap(value = "contentViews", key = "@category", type = HashMap.class, componentType = DocumentContentViews.class)
121    protected Map<String, DocumentContentViews> contentViews;
122
123    // for bundle update::
124    @XNode("@remove")
125    protected boolean remove = false;
126
127    public String[] getActions() {
128        return actions;
129    }
130
131    public void setActions(String[] actions) {
132        this.actions = actions;
133    }
134
135    public String getIcon() {
136        return icon;
137    }
138
139    public void setIcon(String icon) {
140        this.icon = icon;
141    }
142
143    public String getBigIcon() {
144        return bigIcon;
145    }
146
147    public void setBigIcon(String bigIcon) {
148        this.bigIcon = bigIcon;
149    }
150
151    public String getBigIconExpanded() {
152        return bigIconExpanded;
153    }
154
155    public void setBigIconExpanded(String bigIconExpanded) {
156        this.bigIconExpanded = bigIconExpanded;
157    }
158
159    public String getLabel() {
160        return label;
161    }
162
163    public void setLabel(String label) {
164        this.label = label;
165    }
166
167    public String getId() {
168        return id;
169    }
170
171    public void setId(String id) {
172        this.id = id;
173    }
174
175    public String getDescription() {
176        return description;
177    }
178
179    public void setDescription(String description) {
180        this.description = description;
181    }
182
183    public String getCategory() {
184        return category;
185    }
186
187    public void setCategory(String category) {
188        this.category = category;
189    }
190
191    /**
192     * Returns layout names given a mode.
193     */
194    public String[] getLayouts(String mode) {
195        // default to mode ANY
196        return getLayouts(mode, BuiltinModes.ANY);
197    }
198
199    public String[] getLayouts(String mode, String defaultMode) {
200        if (layouts != null) {
201            Layouts layouts = this.layouts.get(mode);
202            if (layouts == null && defaultMode != null) {
203                layouts = this.layouts.get(defaultMode);
204            }
205            if (layouts != null) {
206                return layouts.getLayouts();
207            }
208        }
209        return null;
210    }
211
212    /**
213     * Returns the layouts map
214     */
215    public Map<String, Layouts> getLayouts() {
216        return Collections.unmodifiableMap(layouts);
217    }
218
219    public void setLayouts(Map<String, Layouts> layouts) {
220        this.layouts = layouts;
221    }
222
223    public String getDefaultView() {
224        return defaultView;
225    }
226
227    public void setDefaultView(String defaultView) {
228        this.defaultView = defaultView;
229    }
230
231    public String getCreateView() {
232        return createView;
233    }
234
235    public void setCreateView(String createView) {
236        this.createView = createView;
237    }
238
239    public String getEditView() {
240        return editView;
241    }
242
243    public void setEditView(String editView) {
244        this.editView = editView;
245    }
246
247    public TypeView[] getViews() {
248        return views.values().toArray(new TypeView[views.size()]);
249    }
250
251    @XNodeList(value = "views/view", type = TypeView[].class, componentType = TypeView.class)
252    public void setViews(TypeView[] views) {
253        this.views = new HashMap<String, TypeView>();
254        for (TypeView view : views) {
255            this.views.put(view.getId(), view);
256        }
257    }
258
259    public TypeView getView(String viewId) {
260        return views.get(viewId);
261    }
262
263    public void setView(TypeView view) {
264        views.put(view.getId(), view);
265    }
266
267    public String[] getDeniedSubTypes() {
268        return deniedSubTypes;
269    }
270
271    public void setDeniedSubTypes(String[] deniedSubTypes) {
272        this.deniedSubTypes = deniedSubTypes;
273    }
274
275    public Map<String, SubType> getAllowedSubTypes() {
276        return allowedSubTypes;
277    }
278
279    public void setAllowedSubTypes(Map<String, SubType> allowedSubTypes) {
280        this.allowedSubTypes = allowedSubTypes;
281    }
282
283    public boolean getRemove() {
284        return remove;
285    }
286
287    public void setRemove(boolean remove) {
288        this.remove = remove;
289    }
290
291    @Override
292    public String toString() {
293        final StringBuilder buf = new StringBuilder();
294        buf.append(Type.class.getSimpleName());
295        buf.append(" {");
296        buf.append("id: ");
297        buf.append(id);
298        buf.append('}');
299        return buf.toString();
300    }
301
302    public String getIconExpanded() {
303        return iconExpanded;
304    }
305
306    public void setIconExpanded(String iconExpanded) {
307        this.iconExpanded = iconExpanded;
308    }
309
310    /**
311     * Return content views defined on this document type for given category
312     *
313     * @since 5.4
314     */
315    public String[] getContentViews(String category) {
316        if (contentViews != null) {
317            DocumentContentViews cv = contentViews.get(category);
318            if (cv != null) {
319                return cv.getContentViewNames();
320            }
321        }
322        return null;
323    }
324
325    public Map<String, DocumentContentViews> getContentViews() {
326        return Collections.unmodifiableMap(contentViews);
327    }
328
329    public void setContentViews(Map<String, DocumentContentViews> contentViews) {
330        this.contentViews = contentViews;
331    }
332
333    /**
334     * Clone method to handle hot reload
335     *
336     * @since 5.6
337     */
338    @Override
339    public Type clone() {
340        Type clone = new Type();
341        clone.setId(getId());
342        clone.setIcon(getIcon());
343        clone.setIconExpanded(getIconExpanded());
344        clone.setBigIcon(getBigIcon());
345        clone.setBigIconExpanded(getBigIconExpanded());
346        clone.setLabel(getLabel());
347        Map<String, SubType> subs = getAllowedSubTypes();
348        if (subs != null) {
349            Map<String, SubType> csubs = new HashMap<String, SubType>();
350            for (Map.Entry<String, SubType> item : subs.entrySet()) {
351                csubs.put(item.getKey(), item.getValue().clone());
352            }
353            clone.setAllowedSubTypes(csubs);
354        }
355        String[] denied = getDeniedSubTypes();
356        if (denied != null) {
357            clone.setDeniedSubTypes(denied.clone());
358        }
359        clone.setDefaultView(getDefaultView());
360        clone.setCreateView(getCreateView());
361        clone.setEditView(getEditView());
362        clone.setDescription(getDescription());
363        clone.setCategory(getCategory());
364        if (views != null) {
365            Map<String, TypeView> cviews = new HashMap<String, TypeView>();
366            for (Map.Entry<String, TypeView> item : views.entrySet()) {
367                cviews.put(item.getKey(), item.getValue().clone());
368            }
369            clone.views = cviews;
370        }
371        String[] actions = getActions();
372        if (actions != null) {
373            clone.setActions(actions.clone());
374        }
375        // do not clone old layout definition, nobody's using it anymore
376        Map<String, Layouts> layouts = getLayouts();
377        if (layouts != null) {
378            Map<String, Layouts> clayouts = new HashMap<String, Layouts>();
379            for (Map.Entry<String, Layouts> item : layouts.entrySet()) {
380                clayouts.put(item.getKey(), item.getValue().clone());
381            }
382            clone.setLayouts(clayouts);
383        }
384        Map<String, DocumentContentViews> cvs = getContentViews();
385        if (cvs != null) {
386            Map<String, DocumentContentViews> ccvs = new HashMap<String, DocumentContentViews>();
387            for (Map.Entry<String, DocumentContentViews> item : cvs.entrySet()) {
388                ccvs.put(item.getKey(), item.getValue().clone());
389            }
390            clone.setContentViews(ccvs);
391        }
392        clone.setRemove(getRemove());
393        return clone;
394    }
395
396}