1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.form.field.definition.migration;
35
36 import info.magnolia.ui.contentapp.FilteringMode;
37 import info.magnolia.ui.datasource.DatasourceDefinition;
38 import info.magnolia.ui.datasource.jcr.JcrDatasource;
39 import info.magnolia.ui.datasource.jcr.JcrDatasourceDefinition;
40 import info.magnolia.ui.datasource.optionlist.Option;
41 import info.magnolia.ui.datasource.optionlist.OptionListDefinition;
42 import info.magnolia.ui.editor.converter.AbstractJcrConverter;
43 import info.magnolia.ui.field.AbstractSelectFieldDefinition;
44 import info.magnolia.ui.form.field.definition.SelectFieldDefinition;
45 import info.magnolia.ui.form.field.definition.SelectFieldOptionDefinition;
46
47 import java.util.Collections;
48 import java.util.List;
49 import java.util.Optional;
50 import java.util.Set;
51 import java.util.stream.Collectors;
52
53 import javax.jcr.Node;
54 import javax.jcr.NodeIterator;
55 import javax.jcr.RepositoryException;
56
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 import com.machinezoo.noexception.Exceptions;
61 import com.vaadin.data.Result;
62 import com.vaadin.data.ValueContext;
63
64
65
66
67
68
69
70
71 public abstract class AbstractSelectFieldDefinitionConverter<T, NEW extends AbstractSelectFieldDefinition<T, DatasourceDefinition>, OLD extends info.magnolia.ui.form.field.definition.SelectFieldDefinition> extends AbstractConfiguredFieldDefinitionConverter <T, NEW, OLD>{
72
73 private final Logger log = LoggerFactory.getLogger(AbstractSelectFieldDefinitionConverter.class);
74
75 @Override
76 public NEW convert(OLD oldDefinition) {
77 NEW newDefinition = super.convert(oldDefinition);
78 newDefinition.setDatasource(createDatasourceDefinition(oldDefinition));
79 newDefinition.setFilteringMode(convertFilteringMode(oldDefinition.getFilteringMode()));
80 if (oldDefinition.getOptions() == null || oldDefinition.getOptions().isEmpty()) {
81 newDefinition.setConverterClass((Class) JcrNodeToOptionValueConverter.class);
82 }
83 return newDefinition;
84 }
85
86 String resolveDefaultValue(OLD oldDefinition) {
87 return resolveDefaultValues(oldDefinition)
88 .stream()
89 .findFirst()
90 .orElse(oldDefinition.getDefaultValue());
91 }
92
93 Set<String> resolveDefaultValues(OLD oldDefinition) {
94 Set<String> selectedOptions = Optional.ofNullable(oldDefinition.getOptions())
95 .orElse(Collections.emptyList())
96 .stream()
97 .filter(SelectFieldOptionDefinition::isSelected)
98 .map(option -> Optional.ofNullable(option.getValue()).orElse(option.getName()))
99 .collect(Collectors.toSet());
100
101 if (!selectedOptions.isEmpty()) {
102 return selectedOptions;
103 }
104 return Optional.ofNullable(oldDefinition.getDefaultValue())
105 .map(Collections::singleton)
106 .orElseGet(Collections::emptySet);
107 }
108
109 DatasourceDefinition createDatasourceDefinition(SelectFieldDefinition oldDefinition) {
110 if (oldDefinition.getOptions() != null && !oldDefinition.getOptions().isEmpty()) {
111 return createOptionListDefinition(oldDefinition);
112 }
113 return createJcrDatasourceDefinition(oldDefinition);
114 }
115
116 OptionListDefinition createOptionListDefinition(SelectFieldDefinition oldDefinition) {
117 List<Option> options = oldDefinition.getOptions().stream()
118 .map(selectFieldOptionDefinition -> {
119 Option option = new Option();
120 option.setValue(Optional.ofNullable(selectFieldOptionDefinition.getValue()).orElse(selectFieldOptionDefinition.getName()));
121 option.setName(selectFieldOptionDefinition.getName());
122 option.setLabel(selectFieldOptionDefinition.getLabel());
123 option.setIconSrc(selectFieldOptionDefinition.getIconSrc());
124 return option;
125 })
126 .collect(Collectors.toList());
127
128 OptionListDefinition optionListDefinition = new OptionListDefinition();
129 optionListDefinition.setSortable(oldDefinition.isSortOptions());
130 optionListDefinition.setOptions(options);
131 return optionListDefinition;
132 }
133
134 JcrDatasourceDefinition createJcrDatasourceDefinition(SelectFieldDefinition oldDefinition) {
135 JcrDatasourceDefinition jcrDatasourceDefinition = new JcrDatasourceDefinition();
136 jcrDatasourceDefinition.setSortable(oldDefinition.isSortOptions());
137 jcrDatasourceDefinition.setSortByProperties(Collections.singletonList("jcrName"));
138 jcrDatasourceDefinition.setRootPath(oldDefinition.getPath());
139 jcrDatasourceDefinition.setWorkspace(oldDefinition.getRepository());
140 jcrDatasourceDefinition.setDescribeByProperty(oldDefinition.getLabelProperty());
141 return jcrDatasourceDefinition;
142 }
143
144 private FilteringMode convertFilteringMode(com.vaadin.v7.shared.ui.combobox.FilteringMode filteringMode) {
145 switch (filteringMode) {
146 case CONTAINS:
147 return FilteringMode.CONTAINS;
148 case OFF:
149 return FilteringMode.OFF;
150 case STARTSWITH:
151 return FilteringMode.STARTSWITH;
152 }
153 return null;
154 }
155
156 @Override
157 public boolean supports(OLD oldDefinition) {
158 if (!oldDefinition.getValueProperty().equals("value")) {
159 log.warn("Converting non-default " + oldDefinition.getClass() + "#valueProperty not supported.");
160 return false;
161 }
162 return super.supports(oldDefinition);
163 }
164
165
166
167
168
169 public static class JcrNodeToOptionValueConverter extends AbstractJcrConverter<Node> {
170
171 private JcrDatasourceDefinition datasourceDefinition;
172
173 public JcrNodeToOptionValueConverter(JcrDatasource datasource, JcrDatasourceDefinition datasourceDefinition) {
174 super(datasource);
175 this.datasourceDefinition = datasourceDefinition;
176 }
177
178 @Override
179 public Result<String> convertToModel(Node node, ValueContext context) {
180 return Result.ok(Exceptions.wrap().get(() -> getValueOrName(node)));
181 }
182
183 @Override
184 public Node convertToPresentation(String value, ValueContext context) {
185 return Exceptions.wrap().get(() -> getNodeByValuePropertyOrByName(value));
186 }
187
188 private String getValueOrName(Node node) throws RepositoryException {
189 if (node == null) {
190 return null;
191 }
192 return node.hasProperty("value") ? node.getProperty("value").getValue().getString() : node.getName();
193 }
194
195 private Node getNodeByValuePropertyOrByName(String value) throws RepositoryException {
196 Node nodeByName = null;
197 if (value != null) {
198 NodeIterator iterator = getNodeByPath(datasourceDefinition.getRootPath()).getNodes();
199 while (iterator.hasNext()) {
200 Node node = iterator.nextNode();
201 if (node.hasProperty("value") && node.getProperty("value").getValue().getString().equals(value)) {
202 return node;
203 }
204 if (!node.hasProperty("value") && node.getName().equals(value)) {
205 nodeByName = node;
206 }
207 }
208 }
209 return nodeByName;
210 }
211 }
212 }