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.transformer.basic;
35
36 import info.magnolia.objectfactory.Components;
37 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
38 import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
39 import info.magnolia.ui.form.field.transformer.Transformer;
40 import info.magnolia.ui.form.field.transformer.UndefinedPropertyType;
41 import info.magnolia.ui.vaadin.integration.jcr.DefaultPropertyUtil;
42
43 import java.util.Locale;
44 import java.util.Objects;
45
46 import javax.inject.Inject;
47
48 import org.apache.commons.lang3.StringUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import com.vaadin.v7.data.Item;
53 import com.vaadin.v7.data.Property;
54 import com.vaadin.v7.data.util.ObjectProperty;
55
56
57
58
59
60
61
62
63
64
65 public class BasicTransformer<T> implements Transformer<T> {
66 private static final Logger log = LoggerFactory.getLogger(BasicTransformer.class);
67
68 protected final ConfiguredFieldDefinition definition;
69
70 protected Item relatedFormItem;
71
72 protected String basePropertyName;
73
74
75
76
77 @Deprecated
78 protected String i18NPropertyName;
79 private Locale locale;
80 protected Class<T> type;
81
82 private boolean isReadOnly = false;
83
84 private I18NAuthoringSupport i18NAuthoringSupport;
85
86 @Inject
87 public BasicTransformer(Item relatedFormItem, ConfiguredFieldDefinition definition, Class<T> type, I18NAuthoringSupport i18NAuthoringSupport) {
88 this.definition = definition;
89 this.relatedFormItem = relatedFormItem;
90 this.i18NAuthoringSupport = i18NAuthoringSupport;
91 this.basePropertyName = definition.getName();
92
93 setType(type);
94 }
95
96
97
98
99 @Deprecated
100 public BasicTransformer(Item relatedFormItem, ConfiguredFieldDefinition definition, Class<T> type) {
101 this(relatedFormItem, definition, type, Components.getComponent(I18NAuthoringSupport.class));
102 }
103
104 public Item getRelatedFormItem() {
105 return relatedFormItem;
106 }
107
108 @Override
109 public void writeToItem(T newValue) {
110 Property<T> p = getOrCreateProperty(type);
111 p.setValue(newValue);
112 }
113
114 @Override
115 public T readFromItem() {
116 return getOrCreateProperty(type).getValue();
117 }
118
119
120
121
122
123
124 protected void setType(Class<T> typeFromDefinition) {
125 if (typeFromDefinition.isAssignableFrom(UndefinedPropertyType.class)) {
126 String propertyName = definePropertyName();
127 Property<T> property = relatedFormItem.getItemProperty(propertyName);
128 if (property != null) {
129 this.type = (Class<T>) property.getType();
130 } else {
131 this.type = (Class<T>) String.class;
132 }
133 } else {
134 this.type = typeFromDefinition;
135 }
136 }
137
138
139
140
141
142
143
144
145 protected <T> Property<T> getOrCreateProperty(Class<T> type) {
146 return getOrCreateProperty(type, true);
147 }
148
149
150
151
152
153
154 protected <T> Property<T> getOrCreateProperty(Class<T> type, boolean checkTypes) {
155 String propertyName = definePropertyName();
156 Property<T> property = relatedFormItem.getItemProperty(propertyName);
157
158 if (property == null) {
159 property = new ObjectProperty<>(null, type);
160 relatedFormItem.addItemProperty(propertyName, property);
161
162 } else if (checkTypes && !type.isAssignableFrom(property.getType())) {
163
164
165
166 String stringValue = ((property.getValue() != null && StringUtils.isNotBlank(property.getValue().toString()))
167 ? property.getValue().toString()
168 : null);
169 T value = null;
170 try {
171
172 value = (T) DefaultPropertyUtil.createTypedValue(type, stringValue);
173 } catch (Exception e) {
174
175 }
176 if (!Objects.equals(value, property.getValue())) {
177 property = new ObjectProperty<>(value, type, property.isReadOnly());
178
179 relatedFormItem.addItemProperty(propertyName, property);
180 }
181 }
182
183
184 this.isReadOnly = property.isReadOnly();
185 return property;
186 }
187
188
189
190
191 protected String definePropertyName() {
192 final String propertyName = deriveLocaleAwareName(this.basePropertyName);
193 this.i18NPropertyName = propertyName;
194 return propertyName;
195 }
196
197 protected String deriveLocaleAwareName(String baseName) {
198 if (hasI18NSupport() && locale != null && !i18NAuthoringSupport.isDefaultLocale(locale, relatedFormItem)) {
199 return i18NAuthoringSupport.deriveLocalisedPropertyName(baseName, locale);
200 }
201 return baseName;
202 }
203
204 protected I18NAuthoringSupport getI18NAuthoringSupport() {
205 return i18NAuthoringSupport;
206 }
207
208
209
210 @Override
211 public void setLocale(Locale locale) {
212 this.locale = locale;
213 }
214
215 @Override
216 public void setI18NPropertyName(String i18nPropertyName) {
217 log.warn("BasicTransformer.setI18NPropertyName() is deprecated since 5.4.2 without replacement, override BasicTransformer.definePropertyName() and construct the locale-specific property name there if needed.");
218 }
219
220 @Override
221 public Locale getLocale() {
222 return this.locale;
223 }
224
225 @Override
226 public String getBasePropertyName() {
227 return basePropertyName;
228 }
229
230 @Override
231 public boolean hasI18NSupport() {
232 return definition.isI18n();
233 }
234
235 @Override
236 public Class<T> getType() {
237 return type;
238 }
239
240 @Override
241 public boolean isReadOnly() {
242 return this.isReadOnly;
243 }
244
245 @Override
246 @Deprecated
247 public void setReadOnly(boolean isReadOnly) {
248 log.warn("Transformer #readOnly cannot be set, it just mirrors read-only state of the underlying Property.");
249 }
250 }