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.jcr.node2bean.impl;
35
36 import info.magnolia.jcr.node2bean.PropertyTypeDescriptor;
37 import info.magnolia.jcr.node2bean.TransformationState;
38 import info.magnolia.jcr.node2bean.TypeDescriptor;
39 import info.magnolia.jcr.node2bean.TypeMapping;
40 import info.magnolia.objectfactory.ComponentProvider;
41
42 import java.lang.reflect.Array;
43 import java.lang.reflect.Method;
44 import java.util.Collection;
45 import java.util.LinkedList;
46 import java.util.Map;
47
48 import javax.jcr.RepositoryException;
49
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 import com.google.common.base.Predicate;
54 import com.google.common.collect.Iterables;
55 import com.google.common.collect.Maps;
56
57
58
59
60 public class CollectionPropertyHidingTransformer extends Node2BeanTransformerImpl {
61
62 private static final Logger log = LoggerFactory.getLogger(CollectionPropertyHidingTransformer.class);
63
64 private Class<?> beanClass;
65
66 private String collectionName;
67
68 private TypeDescriptor type;
69
70 private PropertyTypeDescriptor propertyDescriptor;
71
72 private Method writeMethod;
73
74 private TypeDescriptor propertyType;
75
76
77
78
79
80 public CollectionPropertyHidingTransformer(Class<?> beanClass, String collectionName) {
81 this.beanClass = beanClass;
82 this.collectionName = collectionName;
83 }
84
85 @Override
86 protected TypeDescriptor onResolveType(TypeMapping typeMapping, TransformationState state, TypeDescriptor resolvedType, ComponentProvider componentProvider) {
87
88 if (type == null) {
89 type = typeMapping.getTypeDescriptor(beanClass);
90 propertyDescriptor = type.getPropertyTypeDescriptor(collectionName, typeMapping);
91 writeMethod = propertyDescriptor.getWriteMethod();
92 propertyType = propertyDescriptor.getCollectionEntryType();
93 }
94
95 if (resolvedType == null) {
96
97
98
99
100
101 if (state.getLevel() > 1 && state.getCurrentType().equals(type)) {
102
103
104 resolvedType = getPropertyType();
105 }
106 }
107 return resolvedType;
108 }
109
110 @Override
111 public void setProperty(TypeMapping mapping, TransformationState state, PropertyTypeDescriptor descriptor, Map<String, Object> values) throws RepositoryException {
112 if (descriptor.getName().equals(collectionName)) {
113 Object bean = state.getCurrentBean();
114
115 Map<String, Object> value = Maps.filterValues(values, new Predicate<Object>() {
116 @Override
117 public boolean apply(Object input) {
118 return getPropertyType().getType().isInstance(input);
119 }
120 });
121
122 try {
123 if (propertyDescriptor.isMap()) {
124 writeMethod.invoke(bean, value);
125 } else if (propertyDescriptor.isArray()) {
126 Class<?> entryClass = getPropertyType().getType();
127 Collection<Object> list = new LinkedList<Object>(value.values());
128
129 Object[] arr = (Object[]) Array.newInstance(entryClass, list.size());
130
131 for (int i = 0; i < arr.length; i++) {
132 arr[i] = Iterables.get(list, i);
133 }
134 writeMethod.invoke(bean, new Object[]{arr});
135 } else if (propertyDescriptor.isCollection()) {
136 Collection<?> collection = createCollectionFromMap(value, propertyDescriptor.getType().getType());
137 writeMethod.invoke(bean, collection);
138 }
139 } catch (Exception e) {
140 log.error("Can't call set method {}", propertyDescriptor.getWriteMethod(), e);
141 }
142 } else {
143 super.setProperty(mapping, state, descriptor, values);
144 }
145 }
146
147 public TypeDescriptor getPropertyType() {
148 return propertyType;
149 }
150 }