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.jcr.iterator.FilteringPropertyIterator;
37 import info.magnolia.jcr.predicate.JCRMgnlPropertyHidingPredicate;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.jcr.util.PropertyUtil;
41 import info.magnolia.jcr.wrapper.JCRMgnlPropertiesFilteringNodeWrapper;
42 import info.magnolia.objectfactory.Components;
43 import info.magnolia.ui.api.i18n.I18NAuthoringSupport;
44 import info.magnolia.ui.form.field.definition.CompositeFieldDefinition;
45 import info.magnolia.ui.form.field.definition.ConfiguredFieldDefinition;
46 import info.magnolia.ui.form.field.definition.MultiValueFieldDefinition;
47 import info.magnolia.ui.form.field.transformer.TransformedProperty;
48 import info.magnolia.ui.form.field.transformer.Transformer;
49 import info.magnolia.ui.vaadin.integration.jcr.JcrNewNodeAdapter;
50 import info.magnolia.ui.vaadin.integration.jcr.JcrNodeAdapter;
51
52 import java.util.ArrayList;
53 import java.util.Iterator;
54 import java.util.List;
55
56 import javax.inject.Inject;
57 import javax.jcr.Node;
58 import javax.jcr.NodeIterator;
59 import javax.jcr.Property;
60 import javax.jcr.PropertyIterator;
61 import javax.jcr.RepositoryException;
62
63 import org.apache.commons.lang3.math.NumberUtils;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 import com.vaadin.v7.data.Item;
68 import com.vaadin.v7.data.util.ObjectProperty;
69 import com.vaadin.v7.data.util.PropertysetItem;
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public class MultiValueSubChildrenNodePropertiesTransformer extends MultiValueChildrenNodeTransformer {
93
94 private static final Logger log = LoggerFactory.getLogger(MultiValueSubChildrenNodeTransformer.class);
95
96 private final MultiValueFieldDefinition definition;
97
98
99
100
101 @Deprecated
102 public MultiValueSubChildrenNodePropertiesTransformer(Item relatedFormItem, MultiValueFieldDefinition definition, Class<PropertysetItem> type) {
103 this(relatedFormItem, definition, type, Components.getComponent(I18NAuthoringSupport.class));
104 }
105
106 @Inject
107 public MultiValueSubChildrenNodePropertiesTransformer(Item relatedFormItem, MultiValueFieldDefinition definition, Class<PropertysetItem> type, I18NAuthoringSupport i18NAuthoringSupport) {
108 super(relatedFormItem, definition, type, i18NAuthoringSupport);
109 this.definition = definition;
110 }
111
112 @Override
113 protected JcrNodeAdapter getRootItem() {
114 JcrNodeAdapter res = null;
115 try {
116 res = getOrCreateChildNode(definition.getName(), childNodeType);
117 } catch (RepositoryException re) {
118 log.warn("Not able to retrieve or create a sub node for the parent node {}", ((JcrNodeAdapter) relatedFormItem).getItemId());
119 }
120 return res;
121 }
122
123 @Override
124 protected void handleRootitemAndParent(JcrNodeAdapter rootItem) {
125
126 if (rootItem.getChildren() != null && !rootItem.getChildren().isEmpty()) {
127 ((JcrNodeAdapter) relatedFormItem).addChild(rootItem);
128 } else {
129 ((JcrNodeAdapter) relatedFormItem).removeChild(rootItem);
130 }
131 }
132
133 @Override
134 protected PropertysetItem getValueFromChildNode(Node child) {
135 PropertysetItem newValues = new PropertysetItem();
136 try {
137
138 PropertyIterator iterator = new JCRMgnlPropertiesFilteringNodeWrapper(child).getProperties();
139 while (iterator.hasNext()) {
140 Property jcrProperty = iterator.nextProperty();
141 Object propertyObject = PropertyUtil.getPropertyValueObject(child, jcrProperty.getName());
142 com.vaadin.v7.data.Property newProperty = new ObjectProperty<>(propertyObject);
143
144 newValues.addItemProperty(NumberUtils.isNumber(jcrProperty.getName()) ? Integer.valueOf(jcrProperty.getName()) : jcrProperty.getName(), newProperty);
145 }
146
147 NodeIterator iter = child.getNodes();
148 while (iter.hasNext()) {
149 Node childNode = iter.nextNode();
150 PropertysetItem vals = getValueFromChildNode(childNode);
151 MultiValueFieldDefinition subChildDefinition = null;
152 for (ConfiguredFieldDefinition field : ((CompositeFieldDefinition) definition.getField()).getFields()) {
153 if (field.getName().equals(childNode.getName())) {
154 subChildDefinition = (MultiValueFieldDefinition) field;
155 break;
156 }
157 }
158 Transformer<PropertysetItem> subChildTransformer = (Transformer<PropertysetItem>) Components.newInstance(subChildDefinition.getTransformerClass(), new JcrNodeAdapter(childNode), subChildDefinition, PropertysetItem.class);
159 TransformedProperty<PropertysetItem> prop = new TransformedProperty<>(subChildTransformer);
160 prop.setValue(vals);
161 newValues.addItemProperty(childNode.getName(), prop);
162 }
163 } catch (RepositoryException re) {
164 log.warn("Not able to read property from the following child node {}", NodeUtil.getName(child), re.getLocalizedMessage());
165 }
166 return newValues;
167 }
168
169 @Override
170 protected void setChildItemValue(JcrNodeAdapter childItem, Object newValues) {
171 if (!(newValues instanceof PropertysetItem)) {
172 super.setChildItemValue(childItem, newValues);
173 return;
174 }
175 PropertysetItem newPropertySetValues = (PropertysetItem) newValues;
176
177
178 List<String> propertyNamesAsString = new ArrayList<>();
179 Iterator<?> propertyNames = newPropertySetValues.getItemPropertyIds().iterator();
180 while (propertyNames.hasNext()) {
181
182 Object propertyName = propertyNames.next();
183 String propertyNameString = propertyName.toString();
184 propertyNamesAsString.add(propertyNameString);
185 com.vaadin.v7.data.Property storedProperty = childItem.getItemProperty(propertyName);
186 com.vaadin.v7.data.Property newProperty = newPropertySetValues.getItemProperty(propertyName);
187 if (newProperty != null) {
188 if (storedProperty != null) {
189 storedProperty.setValue(newProperty.getValue());
190 } else {
191 Object value = newProperty.getValue();
192 if (value instanceof PropertysetItem) {
193
194 JcrNodeAdapter child;
195 try {
196 if (childItem.getJcrItem().hasNode(propertyNameString)) {
197 Node node = childItem.getJcrItem().getNode(propertyNameString);
198 child = new JcrNodeAdapter(node);
199 } else {
200 child = new JcrNewNodeAdapter(childItem.getJcrItem(), NodeTypes.ContentNode.NAME);
201 child.setNodeName(propertyNameString);
202 }
203 childItem.addChild(child);
204 setChildItemValue(child, value);
205 } catch (RepositoryException e) {
206 log.error("Failed to persist property " + propertyName + " (" + propertyName.getClass().getName() + ") with " + e.getMessage(), e);
207 throw new RuntimeException(e);
208 }
209 } else {
210 childItem.addItemProperty(propertyName, newProperty);
211 }
212 }
213 }
214 }
215
216 try {
217 FilteringPropertyIterator iter = new FilteringPropertyIterator(childItem.getJcrItem().getProperties(), new JCRMgnlPropertyHidingPredicate());
218 while (iter.hasNext()) {
219 Property prop = iter.nextProperty();
220 if (!propertyNamesAsString.contains(prop.getName())) {
221 childItem.removeItemProperty(prop.getName());
222 }
223 }
224 } catch (RepositoryException e) {
225 log.error("Failed to remove old property from " + childItem + " with " + e.getMessage(), e);
226 throw new RuntimeException(e);
227 }
228 }
229 }