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.content2bean.impl;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.NodeData;
38 import info.magnolia.cms.util.ExtendingContentWrapper;
39 import info.magnolia.cms.util.NodeDataUtil;
40 import info.magnolia.content2bean.Content2BeanException;
41 import info.magnolia.content2bean.Content2BeanProcessor;
42 import info.magnolia.content2bean.Content2BeanTransformer;
43 import info.magnolia.content2bean.PropertyTypeDescriptor;
44 import info.magnolia.content2bean.TransformationState;
45 import info.magnolia.content2bean.TypeDescriptor;
46 import info.magnolia.content2bean.TypeMapping;
47 import info.magnolia.objectfactory.ComponentProvider;
48
49 import java.util.Collection;
50 import java.util.LinkedHashMap;
51 import java.util.Map;
52
53 import javax.inject.Inject;
54 import javax.inject.Singleton;
55 import javax.jcr.RepositoryException;
56
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
61
62
63
64
65 @Deprecated
66 @Singleton
67 public class Content2BeanProcessorImpl implements Content2BeanProcessor {
68 private static final Logger log = LoggerFactory.getLogger(Content2BeanProcessorImpl.class);
69
70 private final TypeMapping typeMapping;
71
72 private boolean forceCreation = true;
73
74 @Inject
75 public Content2BeanProcessorImpl(TypeMapping typeMapping) {
76 this.typeMapping = typeMapping;
77 }
78
79 @Override
80 public Object toBean(Content node, boolean recursive, final Content2BeanTransformer transformer, ComponentProvider componentProvider) throws Content2BeanException {
81 return toBean(new ExtendingContentWrapper(node), recursive, transformer, transformer.newState(), componentProvider);
82 }
83
84 protected Object toBean(Content node, boolean recursive, Content2BeanTransformer transformer, TransformationState state, ComponentProvider componentProvider) throws Content2BeanException {
85
86 state.pushContent(node);
87
88 TypeDescriptor type = null;
89 try {
90 type = transformer.resolveType(typeMapping, state, componentProvider);
91 } catch (Throwable e) {
92 if (isForceCreation()) {
93 log.warn("can't resolve class for node {}", node.getHandle(), e);
94 } else {
95 throw new Content2BeanException("can't resolve class for node " + node.getHandle(), e);
96 }
97 }
98
99 Object bean = null;
100 if (type != null) {
101 state.pushType(type);
102
103 transformer = resolveTransformer(type, transformer);
104
105 Map<String, Object> values = toMap(node, recursive, transformer, state, componentProvider);
106
107 try {
108 bean = transformer.newBeanInstance(state, values, componentProvider);
109 } catch (Throwable e) {
110 if (isForceCreation()) {
111 log.warn("Can't instantiate bean for {}", node.getHandle(), e);
112 } else {
113 throw new Content2BeanException("Can't instantiate bean for " + node.getHandle(), e);
114 }
115 }
116
117 if (bean != null) {
118 state.pushBean(bean);
119
120 setProperties(values, transformer, state);
121
122 transformer.initBean(state, values);
123
124 bean = state.getCurrentBean();
125
126 state.popBean();
127 } else {
128 if (forceCreation) {
129 log.warn("can't instantiate bean of type {} for node {}", type.getType().getName(), node.getHandle());
130 } else {
131 throw new Content2BeanException("can't instantiate bean of type " + type.getType().getName());
132 }
133 }
134
135 state.popType();
136 }
137 state.popContent();
138
139 return bean;
140 }
141
142 @Override
143 public Object setProperties(final Object bean, Content node, boolean recursive, Content2BeanTransformer transformer, ComponentProvider componentProvider) throws Content2BeanException {
144
145 node = new ExtendingContentWrapper(node);
146
147 TransformationState state = transformer.newState();
148 state.pushBean(bean);
149 state.pushContent(node);
150
151
152 TypeDescriptor type = typeMapping.getTypeDescriptor(bean.getClass());
153
154 state.pushType(type);
155
156 transformer = resolveTransformer(type, transformer);
157
158 Map<String, Object> values = toMap(node, recursive, transformer, state, componentProvider);
159
160 setProperties(values, transformer, state);
161
162 transformer.initBean(state, values);
163
164 state.popBean();
165 state.popType();
166 state.popContent();
167
168 return bean;
169 }
170
171
172
173
174 protected Map<String, Object> toMap(Content node, boolean recursive, Content2BeanTransformer transformer, TransformationState state, ComponentProvider componentProvider) throws Content2BeanException {
175 Map<String, Object> map = new LinkedHashMap<String, Object>();
176 for (NodeData nd : node.getNodeDataCollection()) {
177 Object val = NodeDataUtil.getValueObject(nd);
178 if (val != null) {
179 map.put(nd.getName(), val);
180 }
181 }
182
183 if (recursive) {
184 final Collection<Content> children = transformer.getChildren(node);
185 for (Content childNode : children) {
186
187
188
189 Object childBean = toBean(childNode, true, transformer, state, componentProvider);
190
191 if (childBean != null) {
192 String name = childNode.getName();
193 try {
194 if (childNode.getIndex() > 1) {
195 name += childNode.getIndex();
196 }
197 } catch (RepositoryException e) {
198 log.error("can't read index of the node [{}]", childNode, e);
199 }
200 map.put(name, childBean);
201 }
202 }
203 }
204
205 return map;
206 }
207
208
209
210
211
212
213 protected void setProperties(Map<String, Object> values, final Content2BeanTransformer transformer, TransformationState state) throws Content2BeanException {
214 Object bean = state.getCurrentBean();
215 log.debug("will populate bean {} with the values {}", bean.getClass().getName(), values);
216
217 if (bean instanceof Map) {
218 ((Map<String, Object>) bean).putAll(values);
219 }
220
221 if (bean instanceof Collection) {
222 ((Collection<Object>) bean).addAll(values.values());
223 } else {
224
225 TypeDescriptor beanTypeDescriptor = typeMapping.getTypeDescriptor(bean.getClass());
226 final Collection<PropertyTypeDescriptor> dscrs = beanTypeDescriptor.getPropertyDescriptors(typeMapping).values();
227
228 for (PropertyTypeDescriptor descriptor : dscrs) {
229 transformer.setProperty(typeMapping, state, descriptor, values);
230 }
231 }
232 }
233
234 protected Content2BeanTransformerBeanTransformer.html#Content2BeanTransformer">Content2BeanTransformer resolveTransformer(TypeDescriptor type, Content2BeanTransformer transformer) {
235 Content2BeanTransformer customTransformer = type.getTransformer();
236 if (customTransformer != null) {
237 transformer = customTransformer;
238 }
239 return transformer;
240 }
241
242 public boolean isForceCreation() {
243 return this.forceCreation;
244 }
245
246
247
248
249 public void setForceCreation(boolean handleExceptions) {
250 this.forceCreation = handleExceptions;
251 }
252
253 }