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.multi;
35
36 import info.magnolia.annotation.deprecation.MgnlDeprecated;
37
38 import info.magnolia.cms.i18n.I18nContentSupport;
39 import info.magnolia.jcr.util.NodeTypes;
40 import info.magnolia.jcr.util.NodeUtil;
41 import info.magnolia.objectfactory.Components;
42 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
43 import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
44 import info.magnolia.ui.form.field.transformer.basic.BasicTransformer;
45 import info.magnolia.ui.vaadin.integration.jcr.JcrNewNodeAdapter;
46 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
47
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Locale;
51
52 import javax.inject.Inject;
53 import javax.jcr.Node;
54 import javax.jcr.RepositoryException;
55
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 import com.google.common.collect.ImmutableList;
60 import com.vaadin.v7.data.Item;
61 import com.vaadin.v7.data.Property;
62 import com.vaadin.v7.data.util.ObjectProperty;
63 import com.vaadin.v7.data.util.PropertysetItem;
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 @Deprecated
81 @MgnlDeprecated(since = "6.2.3.", description = "Use new framework and ByIndexedChildNodes instead.")
82 public class DelegatingMultiValueFieldTransformer extends BasicTransformer<PropertysetItem> implements MultiTransformer {
83
84 private static final Logger log = LoggerFactory.getLogger(DelegatingMultiValueFieldTransformer.class);
85
86 protected String childNodeType = NodeTypes.ContentNode.NAME;
87
88 protected String subItemBaseName;
89
90 private List<String> delegateItemNames = new ArrayList<>();
91
92 private PropertysetItem delegateAggregatorItem = new PropertysetItem();
93
94
95
96
97
98 @Deprecated
99 public DelegatingMultiValueFieldTransformer(Item relatedFormItem, ConfiguredFieldDefinition definition, Class<PropertysetItem> type, I18nContentSupport i18nContentSupport) {
100 this(relatedFormItem, definition, type, Components.getComponent(I18NAuthoringSupport.class));
101 }
102
103 @Inject
104 public DelegatingMultiValueFieldTransformer(Item relatedFormItem, ConfiguredFieldDefinition definition, Class<PropertysetItem> type, I18NAuthoringSupport i18nAuthoringSupport) {
105 super(relatedFormItem, definition, type, i18nAuthoringSupport);
106 this.subItemBaseName = getSubItemBaseName();
107 }
108
109
110
111
112
113
114
115 @Override
116 public PropertysetItem readFromItem() {
117
118 if (delegateAggregatorItem.getItemPropertyIds().isEmpty()) {
119 JcrNodeAdapter rootItem = getRootItem();
120
121 if (!rootItem.hasChildItemChanges()) {
122 populateStoredChildItems(rootItem);
123 }
124
125 int position = 0;
126 for (String itemName : rootItem.getChildren().keySet()) {
127 if (itemName.matches(childItemRegexRepresentation())) {
128 delegateAggregatorItem.addItemProperty(position, new ObjectProperty<Item>(rootItem.getChild(itemName)));
129 delegateItemNames.add(itemName);
130 ++position;
131 }
132 }
133 }
134 return delegateAggregatorItem;
135 }
136
137
138
139
140 @Override
141 public void writeToItem(PropertysetItem newValue) {
142 log.debug("CALL writeToItem");
143 }
144
145
146
147
148
149
150
151
152 @Override
153 public Property<?> createProperty() {
154 final String newItemName = createNewItemName();
155
156 final JcrNodeAdapter child;
157
158
159 if (getRootItem().getChild(newItemName) instanceof JcrNodeAdapter) {
160 child = (JcrNodeAdapter) getRootItem().getChild(newItemName);
161 } else {
162 child = new JcrNewNodeAdapter(getRootItem().getJcrItem(), childNodeType, newItemName);
163 }
164
165 getRootItem().addChild(child);
166 Property<?> res = new ObjectProperty<Item>(child);
167 delegateAggregatorItem.addItemProperty(delegateAggregatorItem.getItemPropertyIds().size(), res);
168
169 return res;
170 }
171
172 @Override
173 public void removeProperty(Object id) {
174 Property<?> propertyToRemove = delegateAggregatorItem.getItemProperty(id);
175 if (propertyToRemove != null && propertyToRemove.getValue() != null) {
176 JcrNodeAdapter./../../../info/magnolia/ui/vaadin/integration/jcr/JcrNodeAdapter.html#JcrNodeAdapter">JcrNodeAdapter toRemove = (JcrNodeAdapter) propertyToRemove.getValue();
177 toRemove.getParent().removeChild(toRemove);
178 }
179 delegateAggregatorItem.removeItemProperty(id);
180 reorganizeIndex((Integer) id);
181 }
182
183 @Override
184 public void setLocale(Locale locale) {
185 super.setLocale(locale);
186 ImmutableList<Object> propertyIds = ImmutableList.copyOf(delegateAggregatorItem.getItemPropertyIds());
187 for (Object id : propertyIds) {
188 delegateAggregatorItem.removeItemProperty(id);
189 }
190 }
191
192
193
194
195
196
197
198 private void reorganizeIndex(int fromIndex) {
199 int valuesSize = delegateAggregatorItem.getItemPropertyIds().size();
200 if (fromIndex == valuesSize) {
201 return;
202 }
203 while (fromIndex < valuesSize) {
204 int toIndex = fromIndex;
205 ++fromIndex;
206 delegateAggregatorItem.addItemProperty(toIndex, delegateAggregatorItem.getItemProperty(fromIndex));
207 delegateAggregatorItem.removeItemProperty(fromIndex);
208 }
209 }
210
211
212
213
214 protected JcrNodeAdapter getRootItem() {
215 return (JcrNodeAdapter) relatedFormItem;
216 }
217
218
219
220
221
222
223 protected String getSubItemBaseName() {
224 return definition.getName();
225 }
226
227
228
229
230 protected void populateStoredChildItems(JcrNodeAdapter rootItem) {
231 List<Node> childNodes = getStoredChildNodes(rootItem);
232 for (Node child : childNodes) {
233 JcrNodeAdapterntegration/jcr/JcrNodeAdapter.html#JcrNodeAdapter">JcrNodeAdapter item = new JcrNodeAdapter(child);
234 rootItem.addChild(item);
235 }
236 }
237
238
239
240
241 protected List<Node> getStoredChildNodes(JcrNodeAdapter parent) {
242 try {
243 if (!(parent instanceof JcrNewNodeAdapter) && parent.getJcrItem().hasNodes()) {
244 return NodeUtil.asList(NodeUtil.getNodes(parent.getJcrItem(), NodeUtil.MAGNOLIA_FILTER));
245 }
246 } catch (RepositoryException re) {
247 log.warn("Not able to access the Child Nodes of the following Node Identifier {}", parent.getItemId(), re);
248 }
249 return new ArrayList<Node>();
250 }
251
252
253
254
255
256
257
258
259
260
261
262 protected String createNewItemName() {
263 int increment = 0;
264 final List<String> childNodeNames = getChildItemNames();
265 String name;
266 do {
267 name = deriveLocaleAwareName(String.format("%s%d", subItemBaseName, increment));
268 ++increment;
269 } while (childNodeNames.contains(name));
270 return name;
271 }
272
273
274
275
276 protected String childItemRegexRepresentation() {
277 if (hasI18NSupport()) {
278 if (getLocale() == null || getI18NAuthoringSupport().isDefaultLocale(getLocale(), relatedFormItem)) {
279
280
281 return subItemBaseName + incrementRegexRepresentation() + "((?!(_\\w{2}){1,3}))$";
282 } else {
283
284 return getI18NAuthoringSupport().deriveLocalisedPropertyName(subItemBaseName + incrementRegexRepresentation(), getLocale());
285 }
286 } else {
287 return subItemBaseName + incrementRegexRepresentation();
288 }
289 }
290
291 protected String incrementRegexRepresentation() {
292 return "(\\d{1,3})";
293 }
294
295 protected List<String> getChildItemNames() {
296 List<String> res = new ArrayList<>();
297 res.addAll(delegateItemNames);
298 for (Object delegateIds : delegateAggregatorItem.getItemPropertyIds()) {
299 Object value = delegateAggregatorItem.getItemProperty(delegateIds).getValue();
300 if (value instanceof JcrNodeAdapter) {
301 res.add(((JcrNodeAdapter) value).getNodeName());
302 }
303 }
304 return res;
305 }
306
307
308
309 @Override
310 public String getBasePropertyName() {
311 return subItemBaseName;
312 }
313
314 @Override
315 public void setI18NPropertyName(String i18NSubNodeName) {
316 log.warn("DelegatingMultiValueFieldTransformer.setI18NPropertyName is deprecated since 5.4.2 - should you need a different locale-specific node name, it is possible to alter #i18nSuffix field in #setLocale() method.");
317 }
318 }