001/*
002 * (C) Copyright 2018 Nuxeo (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 *     Kevin Leturc <kleturc@nuxeo.com>
018 */
019package org.nuxeo.ecm.platform.forms.layout.export;
020
021import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON;
022import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE;
023
024import java.io.IOException;
025import java.io.Serializable;
026import java.util.List;
027import java.util.Map;
028import java.util.Map.Entry;
029import java.util.TreeMap;
030
031import org.apache.commons.collections.CollectionUtils;
032import org.apache.commons.collections.MapUtils;
033import org.apache.commons.lang3.ArrayUtils;
034import org.apache.commons.lang3.StringUtils;
035import org.nuxeo.ecm.core.io.registry.reflect.Setup;
036import org.nuxeo.ecm.platform.forms.layout.api.FieldDefinition;
037import org.nuxeo.ecm.platform.forms.layout.api.RenderingInfo;
038import org.nuxeo.ecm.platform.forms.layout.api.WidgetDefinition;
039import org.nuxeo.ecm.platform.forms.layout.api.WidgetReference;
040import org.nuxeo.ecm.platform.forms.layout.api.WidgetSelectOption;
041
042import com.fasterxml.jackson.core.JsonGenerator;
043
044/**
045 * @since 10.1
046 */
047@Setup(mode = SINGLETON, priority = REFERENCE)
048public class WidgetDefinitionJsonWriter extends AbstractLayoutJsonWriter<WidgetDefinition> {
049
050    @Override
051    public void write(WidgetDefinition entity, JsonGenerator jg) throws IOException {
052        jg.writeStartObject();
053        jg.writeStringField("name", entity.getName());
054        jg.writeStringField("type", entity.getType());
055        String typeCategory = entity.getTypeCategory();
056        if (StringUtils.isNotBlank(typeCategory)) {
057            jg.writeStringField("typeCategory", typeCategory);
058        }
059
060        Map<String, String> labels = entity.getLabels();
061        if (MapUtils.isNotEmpty(labels)) {
062            writeSerializableMapField("labels", new TreeMap<>(labels), jg);
063        }
064
065        Map<String, String> helpLabels = entity.getHelpLabels();
066        if (MapUtils.isNotEmpty(helpLabels)) {
067            writeSerializableMapField("helpLabels", new TreeMap<>(helpLabels), jg);
068        }
069
070        jg.writeBooleanField("translated", entity.isTranslated());
071        jg.writeBooleanField("handlingLabels", entity.isHandlingLabels());
072
073        Map<String, String> widgetModes = entity.getModes();
074        if (MapUtils.isNotEmpty(widgetModes)) {
075            writeSerializableMapField("widgetModes", new TreeMap<>(widgetModes), jg);
076        }
077
078        FieldDefinition[] fieldDefinitions = entity.getFieldDefinitions();
079        if (ArrayUtils.isNotEmpty(fieldDefinitions)) {
080            jg.writeArrayFieldStart("fields");
081            for (FieldDefinition fieldDefinition : fieldDefinitions) {
082                writeEntity(fieldDefinition, jg);
083            }
084            jg.writeEndArray();
085        }
086
087        WidgetDefinition[] subWidgetDefinitions = entity.getSubWidgetDefinitions();
088        if (ArrayUtils.isNotEmpty(subWidgetDefinitions)) {
089            jg.writeArrayFieldStart("subWidgets");
090            for (WidgetDefinition subWidgetDefinition : subWidgetDefinitions) {
091                writeEntity(subWidgetDefinition, jg);
092            }
093            jg.writeEndArray();
094        }
095
096        WidgetReference[] subWidgetReferences = entity.getSubWidgetReferences();
097        if (ArrayUtils.isNotEmpty(subWidgetReferences)) {
098            jg.writeArrayFieldStart("subWidgetRefs");
099            for (WidgetReference subWidgetReference : subWidgetReferences) {
100                writeEntity(subWidgetReference, jg);
101            }
102            jg.writeEndArray();
103        }
104
105        Map<String, Map<String, Serializable>> properties = entity.getProperties();
106        if (MapUtils.isNotEmpty(properties) && properties.values().stream().anyMatch(MapUtils::isNotEmpty)) {
107            writeSerializableMapMapField("properties", cleanAndSort(properties), jg);
108        }
109
110        Map<String, Map<String, Serializable>> propertiesByWidgetMode = entity.getWidgetModeProperties();
111        if (MapUtils.isNotEmpty(propertiesByWidgetMode)
112                && propertiesByWidgetMode.values().stream().anyMatch(MapUtils::isNotEmpty)) {
113            writeSerializableMapMapField("propertiesByWidgetMode", cleanAndSort(propertiesByWidgetMode), jg);
114        }
115
116        Map<String, Map<String, Serializable>> controls = entity.getControls();
117        if (MapUtils.isNotEmpty(controls) && controls.values().stream().anyMatch(MapUtils::isNotEmpty)) {
118            writeSerializableMapMapField("controls", cleanAndSort(controls), jg);
119        }
120
121        WidgetSelectOption[] selectOptions = entity.getSelectOptions();
122        if (ArrayUtils.isNotEmpty(selectOptions)) {
123            jg.writeArrayFieldStart("selectOptions");
124            for (WidgetSelectOption selectOption : selectOptions) {
125                writeEntity(selectOption, jg);
126            }
127            jg.writeEndArray();
128        }
129
130        Map<String, List<RenderingInfo>> renderingInfos = entity.getRenderingInfos();
131        if (MapUtils.isNotEmpty(renderingInfos)
132                && renderingInfos.values().stream().anyMatch(CollectionUtils::isNotEmpty)) {
133            jg.writeObjectFieldStart("renderingInfos");
134            // sort so that order is deterministic
135            for (Entry<String, List<RenderingInfo>> entry : new TreeMap<>(renderingInfos).entrySet()) {
136                writeSerializableListField(entry.getKey(), entry.getValue(), jg);
137            }
138            jg.writeEndObject();
139        }
140
141        List<String> aliases = entity.getAliases();
142        if (CollectionUtils.isNotEmpty(aliases)) {
143            writeSerializableListField("aliases", aliases, jg);
144        }
145        jg.writeEndObject();
146    }
147
148}