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