View Javadoc
1   /**
2    * This file Copyright (c) 2018 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.form.definition;
35  
36  import info.magnolia.dynamic.MagnoliaProxy;
37  import info.magnolia.ui.api.action.ActionDefinition;
38  import info.magnolia.ui.api.action.ConfiguredActionDefinition;
39  import info.magnolia.ui.contentapp.action.CloseActionDefinition;
40  import info.magnolia.ui.contentapp.action.CommitActionDefinition;
41  import info.magnolia.ui.dialog.ConfiguredFormDialogDefinition;
42  import info.magnolia.ui.dialog.DialogDefinition;
43  import info.magnolia.ui.dialog.action.CancelDialogActionDefinition;
44  import info.magnolia.ui.dialog.action.SaveDialogActionDefinition;
45  import info.magnolia.ui.field.ConfiguredNamedFieldDefinition;
46  import info.magnolia.ui.field.EditorPropertyDefinition;
47  import info.magnolia.ui.field.NamedFieldDefinition;
48  import info.magnolia.ui.editor.ConfiguredFormDefinition;
49  import info.magnolia.ui.editor.FormDefinition;
50  import info.magnolia.ui.form.action.CancelFormActionDefinition;
51  import info.magnolia.ui.form.action.SaveFormActionDefinition;
52  import info.magnolia.ui.form.field.definition.BasicTextCodeFieldDefinition;
53  import info.magnolia.ui.form.field.definition.BasicUploadFieldDefinition;
54  import info.magnolia.ui.form.field.definition.CheckboxFieldDefinition;
55  import info.magnolia.ui.form.field.definition.CodeFieldDefinition;
56  import info.magnolia.ui.form.field.definition.CompositeFieldDefinition;
57  import info.magnolia.ui.form.field.definition.DateFieldDefinition;
58  import info.magnolia.ui.form.field.definition.HiddenFieldDefinition;
59  import info.magnolia.ui.form.field.definition.LinkFieldDefinition;
60  import info.magnolia.ui.form.field.definition.MultiValueFieldDefinition;
61  import info.magnolia.ui.form.field.definition.OptionGroupFieldDefinition;
62  import info.magnolia.ui.form.field.definition.RichTextFieldDefinition;
63  import info.magnolia.ui.form.field.definition.SelectFieldDefinition;
64  import info.magnolia.ui.form.field.definition.StaticFieldDefinition;
65  import info.magnolia.ui.form.field.definition.SwitchableFieldDefinition;
66  import info.magnolia.ui.form.field.definition.TextFieldDefinition;
67  import info.magnolia.ui.form.field.definition.TwinColSelectFieldDefinition;
68  import info.magnolia.ui.form.field.definition.migration.CheckboxFieldDefinitionConverter;
69  import info.magnolia.ui.form.field.definition.migration.CodeFieldDefinitionConverter;
70  import info.magnolia.ui.form.field.definition.migration.CompositeFieldDefinitionConverter;
71  import info.magnolia.ui.form.field.definition.migration.DateFieldDefinitionConverter;
72  import info.magnolia.ui.form.field.definition.migration.FieldDefinitionConverter;
73  import info.magnolia.ui.form.field.definition.migration.FallbackFieldDefinitionConverter;
74  import info.magnolia.ui.form.field.definition.migration.HiddenFieldDefinitionConverter;
75  import info.magnolia.ui.form.field.definition.migration.LinkFieldDefinitionConverter;
76  import info.magnolia.ui.form.field.definition.migration.MultiValueFieldDefinitionConverter;
77  import info.magnolia.ui.form.field.definition.migration.OptionGroupFieldDefinitionConverter;
78  import info.magnolia.ui.form.field.definition.migration.RichTextFieldDefinitionConverter;
79  import info.magnolia.ui.form.field.definition.migration.SelectFieldDefinitionConverter;
80  import info.magnolia.ui.form.field.definition.migration.StaticFieldDefinitionConverter;
81  import info.magnolia.ui.form.field.definition.migration.SwitchableFieldDefinitionConverter;
82  import info.magnolia.ui.form.field.definition.migration.TextFieldDefinitionConverter;
83  import info.magnolia.ui.form.field.definition.migration.TwinColSelectFieldDefinitionConverter;
84  import info.magnolia.ui.form.field.definition.migration.BasicUploadFieldDefinitionConverter;
85  import info.magnolia.ui.framework.layout.ConfiguredTabDefinition;
86  import info.magnolia.ui.framework.layout.TabDefinition;
87  import info.magnolia.ui.framework.layout.TabbedLayoutDefinition;
88  
89  import java.util.HashMap;
90  import java.util.HashSet;
91  import java.util.List;
92  import java.util.Map;
93  import java.util.Optional;
94  import java.util.Set;
95  import java.util.stream.Collectors;
96  
97  import org.slf4j.Logger;
98  import org.slf4j.LoggerFactory;
99  
100 import net.sf.cglib.proxy.Enhancer;
101 
102 /**
103  * Functional interface for definition converters.
104  *
105  * @param <OLD> - old definition class
106  * @param <NEW> - new definition class
107  *
108  * @deprecated since 6.2.1 - for compatibility use only.
109  */
110 @Deprecated
111 @FunctionalInterface
112 public interface DefinitionConverter<OLD, NEW> {
113 
114     Logger log = LoggerFactory.getLogger(DefinitionConverter.class);
115 
116     NEW convert(OLD definition);
117 
118     Map<Class<? extends info.magnolia.ui.form.field.definition.FieldDefinition>, FieldDefinitionConverter> FIELD_DEFINITION_CONVERTERS = new HashMap<Class<? extends info.magnolia.ui.form.field.definition.FieldDefinition>, FieldDefinitionConverter>() {{
119         put(TextFieldDefinition.class, new TextFieldDefinitionConverter());
120         put(StaticFieldDefinition.class, new StaticFieldDefinitionConverter());
121         put(HiddenFieldDefinition.class, new HiddenFieldDefinitionConverter());
122         put(CodeFieldDefinition.class, new CodeFieldDefinitionConverter());
123         put(BasicTextCodeFieldDefinition.class, new CodeFieldDefinitionConverter());
124         put(CheckboxFieldDefinition.class, new CheckboxFieldDefinitionConverter());
125         put(RichTextFieldDefinition.class, new RichTextFieldDefinitionConverter());
126         put(DateFieldDefinition.class, new DateFieldDefinitionConverter());
127         put(LinkFieldDefinition.class, new LinkFieldDefinitionConverter());
128         put(SelectFieldDefinition.class, new SelectFieldDefinitionConverter());
129         put(OptionGroupFieldDefinition.class, new OptionGroupFieldDefinitionConverter());
130         put(TwinColSelectFieldDefinition.class, new TwinColSelectFieldDefinitionConverter());
131         put(BasicUploadFieldDefinition.class, new BasicUploadFieldDefinitionConverter());
132         put(SwitchableFieldDefinition.class, new SwitchableFieldDefinitionConverter());
133         put(CompositeFieldDefinition.class, new CompositeFieldDefinitionConverter());
134         put(MultiValueFieldDefinition.class, new MultiValueFieldDefinitionConverter());
135     }};
136 
137     DefinitionConverter<info.magnolia.ui.form.field.definition.FieldDefinition, NamedFieldDefinition> NAMED = (oldDefinition) -> {
138         ConfiguredNamedFieldDefinition namedDefinition = new ConfiguredNamedFieldDefinition();
139         namedDefinition.setName(oldDefinition instanceof BasicUploadFieldDefinition ?
140                 ((BasicUploadFieldDefinition) oldDefinition).getBinaryNodeName() :
141                 oldDefinition.getName());
142         return namedDefinition;
143     };
144 
145     DefinitionConverter<info.magnolia.ui.form.definition.TabDefinition, TabDefinition> TAB = (oldDefinition) -> {
146         ConfiguredTabDefinitioninition.html#ConfiguredTabDefinition">ConfiguredTabDefinition newDefinition = new ConfiguredTabDefinition();
147         newDefinition.setLabel(oldDefinition.getLabel());
148         newDefinition.setName(oldDefinition.getName());
149         newDefinition.setFields(oldDefinition.getFields().stream().map(NAMED::convert).collect(Collectors.toList()));
150         return newDefinition;
151     };
152 
153     DefinitionConverter<info.magnolia.ui.form.field.definition.FieldDefinition, EditorPropertyDefinition> FIELD = (oldDefinition) -> {
154         log.debug("Converting old framework field definition [{}] to new definition.", oldDefinition.getName());
155 
156         Class oldDefinitionClass = Enhancer.isEnhanced(oldDefinition.getClass()) || MagnoliaProxy.class.isAssignableFrom(oldDefinition.getClass())
157                 ? oldDefinition.getClass().getSuperclass() : oldDefinition.getClass();
158         FieldDefinitionConverter converter = Optional.of(oldDefinitionClass)
159                 .map(FIELD_DEFINITION_CONVERTERS::get)
160                 .filter(selectedConverter -> selectedConverter.supports(oldDefinition))
161                 .orElse(new FallbackFieldDefinitionConverter());
162         return converter.convert(oldDefinition);
163     };
164 
165     DefinitionConverter<info.magnolia.ui.form.definition.FormDefinition, FormDefinition> FORM = (oldDefinition) -> {
166         TabbedLayoutDefinition tabbedLayoutDefinition = new TabbedLayoutDefinition();
167         tabbedLayoutDefinition.setTabs(oldDefinition.getTabs().stream().map(TAB::convert).collect(Collectors.toList()));
168         ConfiguredFormDefinition<?> newDefinition = new ConfiguredFormDefinition<>();
169         newDefinition.setName(oldDefinition.getLabel());
170         newDefinition.setLayout(tabbedLayoutDefinition);
171         //newDefinition.setImplementationClass();
172         final Set<String> fieldNames = new HashSet<>();
173         List<EditorPropertyDefinition> properties = oldDefinition
174                 .getTabs()
175                 .stream()
176                 .map(info.magnolia.ui.form.definition.TabDefinition::getFields)
177                 .flatMap(List::stream)
178                 .map(FIELD::convert)
179                 .filter(field -> {
180                     if (fieldNames.contains(field.getName())) {
181                         // old form definitions could have more than one (static) fields of the same name on different tabs
182                         log.warn("Removing field with non-unique name: " + field.getName());
183                         return false;
184                     }
185                     fieldNames.add(field.getName());
186                     return true;
187                 })
188                 .collect(Collectors.toList());
189 
190         newDefinition.setProperties(properties);
191         return newDefinition;
192     };
193 
194     DefinitionConverter<ActionDefinition, ActionDefinition> ACTION = (oldDefinition) -> {
195         log.debug("Converting old framework action definition [{}] to new definition.", oldDefinition.getName());
196         if (oldDefinition instanceof SaveFormActionDefinition || oldDefinition instanceof SaveDialogActionDefinition) {
197             return new CommitActionDefinition();
198         } else if (oldDefinition instanceof CancelDialogActionDefinition || oldDefinition instanceof CancelFormActionDefinition) {
199             return new CloseActionDefinition();
200         } else {
201             final ConfiguredActionDefinition configuredActionDefinition = new ConfiguredActionDefinition();
202             configuredActionDefinition.setName("Unsupported action");
203             configuredActionDefinition.setDescription("Please migrate to new framework dialog");
204             return configuredActionDefinition;
205         }
206     };
207 
208     DefinitionConverter<info.magnolia.ui.dialog.definition.FormDialogDefinition, DialogDefinition> DIALOG = (oldDefinition) -> {
209         log.debug("Converting old framework dialog definition [{}] to new definition.",oldDefinition.getId());
210         ConfiguredFormDialogDefinition<Object> newDefinition = new ConfiguredFormDialogDefinition<>();
211         final FormDefinition<Object> convert = FORM.convert(oldDefinition.getForm());
212         newDefinition.setLabel(Optional.ofNullable(oldDefinition.getLabel())
213                 .filter(DefinitionConverter::isNotMessageKey)
214                 .orElse(oldDefinition.getForm().getLabel()));
215         newDefinition.setId(oldDefinition.getId());
216         newDefinition.setLight(oldDefinition.isLight());
217         newDefinition.setForm(convert);
218         newDefinition.setActions(oldDefinition.getActions().entrySet().stream()
219                 .collect(Collectors.toMap(Map.Entry::getKey, entry -> ACTION.convert(entry.getValue())))
220         );
221         return newDefinition;
222     };
223 
224     /**
225      * @deprecated is a hack and should not be used. See MGNLUI-2207.
226      */
227     @Deprecated
228     static boolean isNotMessageKey(final String text) {
229         return text.contains(" ") || !text.contains(".") || text.endsWith(".");
230     }
231 }