1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
package org.apache.portals.graffito.jcr.persistence.objectconverter.impl; |
17 |
|
|
18 |
|
|
19 |
|
import java.util.Iterator; |
20 |
|
import java.util.Map; |
21 |
|
|
22 |
|
import javax.jcr.Node; |
23 |
|
import javax.jcr.PathNotFoundException; |
24 |
|
import javax.jcr.RepositoryException; |
25 |
|
import javax.jcr.Session; |
26 |
|
import javax.jcr.Value; |
27 |
|
import javax.jcr.ValueFactory; |
28 |
|
import javax.jcr.ValueFormatException; |
29 |
|
import javax.jcr.lock.LockException; |
30 |
|
import javax.jcr.nodetype.ConstraintViolationException; |
31 |
|
import javax.jcr.nodetype.NoSuchNodeTypeException; |
32 |
|
import javax.jcr.nodetype.PropertyDefinition; |
33 |
|
import javax.jcr.version.VersionException; |
34 |
|
|
35 |
|
import org.apache.portals.graffito.jcr.exception.JcrMappingException; |
36 |
|
import org.apache.portals.graffito.jcr.exception.PersistenceException; |
37 |
|
import org.apache.portals.graffito.jcr.mapper.Mapper; |
38 |
|
import org.apache.portals.graffito.jcr.mapper.model.BeanDescriptor; |
39 |
|
import org.apache.portals.graffito.jcr.mapper.model.ClassDescriptor; |
40 |
|
import org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor; |
41 |
|
import org.apache.portals.graffito.jcr.mapper.model.FieldDescriptor; |
42 |
|
import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.AtomicTypeConverter; |
43 |
|
import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.AtomicTypeConverterProvider; |
44 |
|
import org.apache.portals.graffito.jcr.persistence.atomictypeconverter.impl.NullTypeConverterImpl; |
45 |
|
import org.apache.portals.graffito.jcr.persistence.collectionconverter.CollectionConverter; |
46 |
|
import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollection; |
47 |
|
import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollectionUtil; |
48 |
|
import org.apache.portals.graffito.jcr.persistence.collectionconverter.impl.DefaultCollectionConverterImpl; |
49 |
|
import org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter; |
50 |
|
import org.apache.portals.graffito.jcr.reflection.ReflectionUtils; |
51 |
|
import org.apache.portals.graffito.jcr.repository.RepositoryUtil; |
52 |
|
|
53 |
|
|
54 |
|
|
55 |
|
|
56 |
|
|
57 |
|
|
58 |
|
|
59 |
|
public class ObjectConverterImpl implements ObjectConverter { |
60 |
0 |
private static final AtomicTypeConverter NULL_CONVERTER = new NullTypeConverterImpl(); |
61 |
|
|
62 |
|
private Mapper mapper; |
63 |
|
|
64 |
|
private AtomicTypeConverterProvider atomicTypeConverterProvider; |
65 |
|
|
66 |
|
|
67 |
|
|
68 |
|
|
69 |
0 |
public ObjectConverterImpl() { |
70 |
0 |
} |
71 |
|
|
72 |
|
|
73 |
|
|
74 |
|
|
75 |
|
|
76 |
|
|
77 |
|
|
78 |
|
|
79 |
0 |
public ObjectConverterImpl(Mapper mapper, AtomicTypeConverterProvider converterProvider) { |
80 |
0 |
this.mapper = mapper; |
81 |
0 |
this.atomicTypeConverterProvider = converterProvider; |
82 |
0 |
} |
83 |
|
|
84 |
|
|
85 |
|
|
86 |
|
|
87 |
|
|
88 |
|
public void setMapper(Mapper mapper) { |
89 |
0 |
this.mapper = mapper; |
90 |
0 |
} |
91 |
|
|
92 |
|
|
93 |
|
|
94 |
|
|
95 |
|
|
96 |
|
|
97 |
|
public void setAtomicTypeConverterProvider(AtomicTypeConverterProvider converterProvider) { |
98 |
0 |
this.atomicTypeConverterProvider = converterProvider; |
99 |
0 |
} |
100 |
|
|
101 |
|
|
102 |
|
|
103 |
|
|
104 |
|
public void insert(Session session, Object object) { |
105 |
0 |
String path = this.getPath(session, object); |
106 |
|
try { |
107 |
0 |
String parentPath = RepositoryUtil.getParentPath(path); |
108 |
0 |
String nodeName = RepositoryUtil.getNodeName(path); |
109 |
0 |
Node parentNode = (Node) session.getItem(parentPath); |
110 |
0 |
this.insert(session, parentNode, nodeName, object); |
111 |
|
|
112 |
0 |
} catch (PathNotFoundException pnfe) { |
113 |
0 |
throw new PersistenceException("Impossible to insert the object at '" + path + "'", |
114 |
|
pnfe); |
115 |
0 |
} catch (RepositoryException re) { |
116 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
117 |
|
"Impossible to insert the object at '" + path + "'", |
118 |
|
re); |
119 |
0 |
} |
120 |
0 |
} |
121 |
|
|
122 |
|
|
123 |
|
|
124 |
|
|
125 |
|
|
126 |
|
public void insert(Session session, Node parentNode, String nodeName, Object object) { |
127 |
0 |
ClassDescriptor classDescriptor = getClassDescriptor(object.getClass()); |
128 |
|
|
129 |
0 |
String jcrNodeType = classDescriptor.getJcrNodeType(); |
130 |
0 |
if ((jcrNodeType == null) || jcrNodeType.equals("")) { |
131 |
0 |
throw new JcrMappingException("Undefined node type for " + parentNode); |
132 |
|
} |
133 |
|
|
134 |
0 |
Node objectNode = null; |
135 |
|
try { |
136 |
0 |
objectNode = parentNode.addNode(nodeName, jcrNodeType); |
137 |
|
} |
138 |
0 |
catch (NoSuchNodeTypeException nsnte) { |
139 |
0 |
throw new JcrMappingException("Unknown node type " + jcrNodeType |
140 |
|
+ " for mapped class " + object.getClass()); |
141 |
|
} |
142 |
0 |
catch (RepositoryException re) { |
143 |
0 |
throw new PersistenceException("Cannot create new node of type " + jcrNodeType |
144 |
|
+ " from mapped class " + object.getClass()); |
145 |
0 |
} |
146 |
|
|
147 |
0 |
if (null != classDescriptor.getJcrMixinTypes()) { |
148 |
0 |
String[] mixinTypes = classDescriptor.getJcrMixinTypes(); |
149 |
0 |
for (int i = 0; i < mixinTypes.length; i++) { |
150 |
|
try { |
151 |
0 |
objectNode.addMixin(mixinTypes[i].trim()); |
152 |
0 |
} catch (NoSuchNodeTypeException nsnte) { |
153 |
0 |
throw new JcrMappingException("Unknown mixin type " + mixinTypes[i].trim() |
154 |
|
+ " for mapped class " + object.getClass()); |
155 |
0 |
} catch (RepositoryException re) { |
156 |
0 |
throw new PersistenceException("Cannot create new node of type " + jcrNodeType |
157 |
|
+ " from mapped class " + object.getClass()); |
158 |
0 |
} |
159 |
|
} |
160 |
|
} |
161 |
|
|
162 |
0 |
if (classDescriptor.usesNodeTypePerHierarchyStrategy()) { |
163 |
|
|
164 |
|
} |
165 |
|
|
166 |
0 |
storeSimpleFields(session, object, classDescriptor, objectNode); |
167 |
0 |
insertBeanFields(session, object, classDescriptor, objectNode); |
168 |
0 |
insertCollectionFields(session, object, classDescriptor, objectNode); |
169 |
0 |
} |
170 |
|
|
171 |
|
|
172 |
|
|
173 |
|
|
174 |
|
public void update(Session session, Object object) { |
175 |
0 |
String path = this.getPath(session, object); |
176 |
|
try { |
177 |
0 |
String parentPath = RepositoryUtil.getParentPath(path); |
178 |
0 |
String nodeName = RepositoryUtil.getNodeName(path); |
179 |
0 |
Node parentNode = (Node) session.getItem(parentPath); |
180 |
0 |
this.update(session, parentNode, nodeName, object); |
181 |
|
} |
182 |
0 |
catch(PathNotFoundException pnfe) { |
183 |
0 |
throw new PersistenceException("Impossible to update the object at '" |
184 |
|
+ path + "'", |
185 |
|
pnfe); |
186 |
|
} |
187 |
0 |
catch(RepositoryException re) { |
188 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
189 |
|
"Impossible to update the object at '" + path + "'", |
190 |
|
re); |
191 |
0 |
} |
192 |
0 |
} |
193 |
|
|
194 |
|
|
195 |
|
|
196 |
|
|
197 |
|
|
198 |
|
public void update(Session session, Node parentNode, String nodeName, Object object) { |
199 |
|
try { |
200 |
0 |
ClassDescriptor classDescriptor = getClassDescriptor(object.getClass()); |
201 |
0 |
Node objectNode = parentNode.getNode(nodeName); |
202 |
|
|
203 |
0 |
if (!objectNode.getPrimaryNodeType().getName().equals(classDescriptor.getJcrNodeType())) { |
204 |
0 |
throw new PersistenceException("Cannot update object of type " |
205 |
|
+ object.getClass().getName() |
206 |
|
+ ". Node type '" |
207 |
|
+ objectNode.getPrimaryNodeType().getName() |
208 |
|
+ "' doesn't match mapping node type '" |
209 |
|
+ classDescriptor.getJcrNodeType() |
210 |
|
+ "'."); |
211 |
|
} |
212 |
|
|
213 |
0 |
storeSimpleFields(session, object, classDescriptor, objectNode); |
214 |
0 |
updateBeanFields(session, object, classDescriptor, objectNode); |
215 |
0 |
updateCollectionFields(session, object, classDescriptor, objectNode); |
216 |
|
} |
217 |
0 |
catch(PathNotFoundException pnfe) { |
218 |
0 |
throw new PersistenceException("Impossible to update the object: " |
219 |
|
+ nodeName |
220 |
|
+ " at node : " + parentNode, pnfe); |
221 |
|
} |
222 |
0 |
catch(RepositoryException re) { |
223 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
224 |
|
"Impossible to update the object: " + nodeName |
225 |
|
+ " at node : " + parentNode, re); |
226 |
0 |
} |
227 |
0 |
} |
228 |
|
|
229 |
|
|
230 |
|
|
231 |
|
|
232 |
|
public Object getObject(Session session, Class clazz, String path) { |
233 |
|
try { |
234 |
0 |
if (!session.itemExists(path)) { |
235 |
0 |
return null; |
236 |
|
} |
237 |
|
|
238 |
0 |
ClassDescriptor classDescriptor = getClassDescriptor(clazz); |
239 |
|
|
240 |
0 |
if (classDescriptor.isAbstract()) { |
241 |
0 |
throw new PersistenceException("Cannot fetch declared abstract object of type " |
242 |
|
+ clazz.getName()); |
243 |
|
} |
244 |
|
|
245 |
0 |
Node node = (Node) session.getItem(path); |
246 |
|
|
247 |
0 |
if (!node.getPrimaryNodeType().getName().equals(classDescriptor.getJcrNodeType()) |
248 |
|
&& |
249 |
|
!("nt:frozenNode".equals(node.getPrimaryNodeType().getName()) |
250 |
|
&& node.getProperty("jcr:frozenPrimaryType").getString().equals(classDescriptor.getJcrNodeType()))) { |
251 |
0 |
throw new PersistenceException("Cannot fetch object of type '" |
252 |
|
+ clazz.getName() |
253 |
|
+ "'. Node type '" |
254 |
|
+ node.getPrimaryNodeType().getName() |
255 |
|
+ "' does not match descriptor node type '" |
256 |
|
+ classDescriptor.getJcrNodeType() |
257 |
|
+ "'"); |
258 |
|
} |
259 |
0 |
if (classDescriptor.usesNodeTypePerHierarchyStrategy()) { |
260 |
0 |
String discriminatorProperty = classDescriptor.getDiscriminatorFieldDescriptor().getJcrName(); |
261 |
|
|
262 |
0 |
if (!node.hasProperty(discriminatorProperty)) { |
263 |
0 |
throw new PersistenceException("Cannot fetch object of type '" |
264 |
|
+ clazz.getName() |
265 |
|
+ "' using NODETYPE_PER_HIERARCHY. Discriminator property is not present."); |
266 |
|
} |
267 |
|
} |
268 |
0 |
Object object = ReflectionUtils.newInstance(clazz); |
269 |
|
|
270 |
0 |
retrieveSimpleFields(session, classDescriptor, node, object); |
271 |
0 |
retrieveBeanFields(session, classDescriptor, node, path, object); |
272 |
0 |
retrieveCollectionFields(session, classDescriptor, node, object); |
273 |
|
|
274 |
0 |
return object; |
275 |
|
} |
276 |
0 |
catch(PathNotFoundException pnfe) { |
277 |
|
|
278 |
0 |
throw new PersistenceException("Impossible to get the object at " + path, pnfe); |
279 |
|
} |
280 |
0 |
catch(RepositoryException re) { |
281 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
282 |
|
"Impossible to get the object at " + path, re); |
283 |
|
} |
284 |
|
} |
285 |
|
|
286 |
|
|
287 |
|
|
288 |
|
|
289 |
|
|
290 |
|
public String getPath(Session session, Object object) { |
291 |
0 |
ClassDescriptor classDescriptor = getClassDescriptor(object.getClass()); |
292 |
|
|
293 |
0 |
final FieldDescriptor pathFieldDescriptor = classDescriptor.getPathFieldDescriptor(); |
294 |
0 |
if (pathFieldDescriptor == null) { |
295 |
0 |
throw new JcrMappingException("Class of type: " |
296 |
|
+ object.getClass().getName() |
297 |
|
+ " has no path mapping. Maybe attribute path=\"true\" for a field element of this class in jcrmapping.xml is missing?" |
298 |
|
); |
299 |
|
} |
300 |
0 |
String pathField = pathFieldDescriptor.getFieldName(); |
301 |
|
|
302 |
0 |
return (String) ReflectionUtils.getNestedProperty(object, pathField); |
303 |
|
} |
304 |
|
|
305 |
|
|
306 |
|
|
307 |
|
|
308 |
|
|
309 |
|
|
310 |
|
|
311 |
|
private Object retrieveSimpleFields(Session session, |
312 |
|
ClassDescriptor classDescriptor, |
313 |
|
Node node, |
314 |
|
Object object) { |
315 |
0 |
Object initializedBean = object; |
316 |
|
try { |
317 |
0 |
Iterator fieldDescriptorIterator = classDescriptor.getFieldDescriptors().iterator(); |
318 |
|
|
319 |
0 |
while (fieldDescriptorIterator.hasNext()) { |
320 |
0 |
FieldDescriptor fieldDescriptor = (FieldDescriptor) fieldDescriptorIterator.next(); |
321 |
|
|
322 |
0 |
String fieldName = fieldDescriptor.getFieldName(); |
323 |
0 |
String propertyName = fieldDescriptor.getJcrName(); |
324 |
|
|
325 |
0 |
if (fieldDescriptor.isPath()) { |
326 |
0 |
if (null == initializedBean) { |
327 |
0 |
initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName()); |
328 |
|
} |
329 |
|
|
330 |
0 |
ReflectionUtils.setNestedProperty(initializedBean, fieldName, node.getPath()); |
331 |
|
} |
332 |
0 |
else if (classDescriptor.usesNodeTypePerHierarchyStrategy() && fieldDescriptor.isDiscriminator()) { |
333 |
0 |
if (null != classDescriptor.getDiscriminatorValue()) { |
334 |
0 |
if (null == initializedBean) { |
335 |
0 |
initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName()); |
336 |
|
} |
337 |
|
|
338 |
0 |
ReflectionUtils.setNestedProperty(initializedBean, fieldName, classDescriptor.getDiscriminatorValue()); |
339 |
|
} |
340 |
|
else { |
341 |
0 |
throw new PersistenceException("Class '" + classDescriptor.getClassName() + "' does not declare a valid discriminator value."); |
342 |
|
} |
343 |
|
} |
344 |
|
else { |
345 |
0 |
if (node.hasProperty(propertyName)) { |
346 |
0 |
Value propValue = node.getProperty(propertyName).getValue(); |
347 |
0 |
if (null != propValue && class="keyword">null == initializedBean) { |
348 |
0 |
initializedBean = ReflectionUtils.newInstance(classDescriptor.getClassName()); |
349 |
|
} |
350 |
|
|
351 |
0 |
AtomicTypeConverter converter= getAtomicTypeConverter(fieldDescriptor, |
352 |
|
initializedBean, |
353 |
|
fieldName); |
354 |
|
|
355 |
0 |
Object fieldValue = converter.getObject(propValue); |
356 |
0 |
ReflectionUtils.setNestedProperty(initializedBean, fieldName, fieldValue); |
357 |
|
} |
358 |
|
} |
359 |
|
} |
360 |
|
} |
361 |
0 |
catch(ValueFormatException vfe) { |
362 |
0 |
throw new PersistenceException( "Cannot retrieve properties of object " |
363 |
|
+ object |
364 |
|
+ " from node " |
365 |
|
+ node, |
366 |
|
vfe); |
367 |
|
} |
368 |
0 |
catch(RepositoryException re) { |
369 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
370 |
|
"Cannot retrieve properties of object " |
371 |
|
+ object |
372 |
|
+ " from node " |
373 |
|
+ node, |
374 |
|
re); |
375 |
0 |
} |
376 |
|
|
377 |
0 |
return initializedBean; |
378 |
|
} |
379 |
|
|
380 |
|
|
381 |
|
|
382 |
|
|
383 |
|
private void retrieveBeanFields(Session session, |
384 |
|
ClassDescriptor classDescriptor, |
385 |
|
Node node, |
386 |
|
String path, |
387 |
|
Object object) { |
388 |
0 |
Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator(); |
389 |
0 |
while (beanDescriptorIterator.hasNext()) { |
390 |
0 |
BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next(); |
391 |
0 |
String beanName = beanDescriptor.getFieldName(); |
392 |
0 |
Class beanClass = ReflectionUtils.getPropertyType(object, beanName); |
393 |
0 |
Object bean = null; |
394 |
0 |
if (beanDescriptor.isInline()) { |
395 |
0 |
bean = this.retrieveSimpleFields(session, getClassDescriptor(beanClass), node, null); |
396 |
|
} |
397 |
0 |
else if (null != beanDescriptor.getBeanConverter()) { |
398 |
0 |
bean = beanDescriptor.getBeanConverter().getObject(session, |
399 |
|
node, |
400 |
|
beanDescriptor, |
401 |
|
beanClass); |
402 |
|
} |
403 |
|
else { |
404 |
0 |
bean = this.getObject(session, |
405 |
|
beanClass, |
406 |
|
path + "/" + beanDescriptor.getJcrName()); |
407 |
|
} |
408 |
0 |
ReflectionUtils.setNestedProperty(object, beanName, bean); |
409 |
|
} |
410 |
0 |
} |
411 |
|
|
412 |
|
|
413 |
|
|
414 |
|
|
415 |
|
private void retrieveCollectionFields(Session session, |
416 |
|
ClassDescriptor classDescriptor, |
417 |
|
Node node, |
418 |
|
Object object) { |
419 |
0 |
Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors() |
420 |
|
.iterator(); |
421 |
0 |
while (collectionDescriptorIterator.hasNext()) { |
422 |
0 |
CollectionDescriptor collectionDescriptor = (CollectionDescriptor) |
423 |
|
collectionDescriptorIterator.next(); |
424 |
0 |
CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor); |
425 |
0 |
Class collectionFieldClass = ReflectionUtils.getPropertyType(object, |
426 |
|
collectionDescriptor.getFieldName()); |
427 |
0 |
ManageableCollection collection = collectionConverter.getCollection(session, |
428 |
|
node, |
429 |
|
collectionDescriptor, |
430 |
|
collectionFieldClass); |
431 |
0 |
ReflectionUtils.setNestedProperty(object, |
432 |
|
collectionDescriptor.getFieldName(), |
433 |
|
collection); |
434 |
|
} |
435 |
0 |
} |
436 |
|
|
437 |
|
|
438 |
|
|
439 |
|
|
440 |
|
private void insertBeanFields(Session session, |
441 |
|
Object object, |
442 |
|
ClassDescriptor classDescriptor, |
443 |
|
Node objectNode) { |
444 |
0 |
Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator(); |
445 |
0 |
while (beanDescriptorIterator.hasNext()) { |
446 |
0 |
BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next(); |
447 |
0 |
String jcrName = beanDescriptor.getJcrName(); |
448 |
0 |
Object bean = ReflectionUtils.getNestedProperty(object, |
449 |
|
beanDescriptor.getFieldName()); |
450 |
0 |
if (bean != null) { |
451 |
0 |
if (beanDescriptor.isInline()) { |
452 |
0 |
this.storeSimpleFields(session, bean, getClassDescriptor(bean.getClass()), objectNode); |
453 |
|
} |
454 |
0 |
else if (null != beanDescriptor.getBeanConverter()) { |
455 |
0 |
beanDescriptor.getBeanConverter().insert(session, |
456 |
|
objectNode, |
457 |
|
beanDescriptor, |
458 |
|
object); |
459 |
|
} |
460 |
|
else { |
461 |
0 |
this.insert(session, objectNode, jcrName, bean); |
462 |
|
} |
463 |
|
} |
464 |
|
} |
465 |
0 |
} |
466 |
|
|
467 |
|
|
468 |
|
|
469 |
|
|
470 |
|
private void updateBeanFields(Session session, |
471 |
|
Object object, |
472 |
|
ClassDescriptor classDescriptor, |
473 |
|
Node objectNode) { |
474 |
0 |
String jcrName = null; |
475 |
|
try { |
476 |
0 |
Iterator beanDescriptorIterator = classDescriptor.getBeanDescriptors().iterator(); |
477 |
0 |
while (beanDescriptorIterator.hasNext()) { |
478 |
0 |
BeanDescriptor beanDescriptor = (BeanDescriptor) beanDescriptorIterator.next(); |
479 |
0 |
jcrName = beanDescriptor.getJcrName(); |
480 |
0 |
Object bean = ReflectionUtils.getNestedProperty(object, |
481 |
|
beanDescriptor.getFieldName()); |
482 |
|
|
483 |
|
|
484 |
0 |
if ((bean == null)) { |
485 |
0 |
if (beanDescriptor.isInline()) { |
486 |
0 |
Class beanClass = ReflectionUtils.getPropertyType(object, beanDescriptor.getFieldName()); |
487 |
0 |
this.storeSimpleFields(session, bean, getClassDescriptor(beanClass), objectNode); |
488 |
|
} |
489 |
0 |
else if (null != beanDescriptor.getBeanConverter()) { |
490 |
0 |
beanDescriptor.getBeanConverter().remove(session, objectNode, beanDescriptor); |
491 |
|
} |
492 |
|
else { |
493 |
0 |
if (objectNode.hasNode(jcrName)) { |
494 |
0 |
objectNode.getNode(jcrName).remove(); |
495 |
|
} |
496 |
|
} |
497 |
|
} |
498 |
|
else { |
499 |
0 |
if (beanDescriptor.isInline()) { |
500 |
0 |
this.storeSimpleFields(session, bean, getClassDescriptor(bean.getClass()), objectNode); |
501 |
|
} |
502 |
0 |
else if (null != beanDescriptor.getBeanConverter()) { |
503 |
0 |
beanDescriptor.getBeanConverter().update(session, |
504 |
|
objectNode, |
505 |
|
beanDescriptor, |
506 |
|
bean); |
507 |
|
} |
508 |
|
else { |
509 |
0 |
this.update(session, objectNode, jcrName, bean); |
510 |
|
} |
511 |
|
} |
512 |
|
} |
513 |
|
} |
514 |
0 |
catch(VersionException ve) { |
515 |
0 |
throw new PersistenceException("Cannot remove bean at path " + jcrName, |
516 |
|
ve); |
517 |
|
} |
518 |
0 |
catch(LockException le) { |
519 |
0 |
throw new PersistenceException("Cannot remove bean at path " + jcrName + ". Item is locked.", |
520 |
|
le); |
521 |
|
} |
522 |
0 |
catch(ConstraintViolationException cve) { |
523 |
0 |
throw new PersistenceException("Cannot remove bean at path " + jcrName + ". Contraint violation.", |
524 |
|
cve); |
525 |
|
} |
526 |
0 |
catch(RepositoryException re) { |
527 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
528 |
|
"Cannot remove bean at path " + jcrName, |
529 |
|
re); |
530 |
0 |
} |
531 |
0 |
} |
532 |
|
|
533 |
|
private void insertCollectionFields(Session session, |
534 |
|
Object object, |
535 |
|
ClassDescriptor classDescriptor, |
536 |
|
Node objectNode) { |
537 |
0 |
Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors() |
538 |
|
.iterator(); |
539 |
0 |
while (collectionDescriptorIterator.hasNext()) { |
540 |
0 |
CollectionDescriptor collectionDescriptor = (CollectionDescriptor) |
541 |
|
collectionDescriptorIterator.next(); |
542 |
0 |
CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor); |
543 |
0 |
Object collection = ReflectionUtils.getNestedProperty(object, collectionDescriptor.getFieldName()); |
544 |
0 |
ManageableCollection manageableCollection = ManageableCollectionUtil |
545 |
|
.getManageableCollection(collection); |
546 |
0 |
collectionConverter.insertCollection(session, |
547 |
|
objectNode, |
548 |
|
collectionDescriptor, |
549 |
|
manageableCollection); |
550 |
|
} |
551 |
0 |
} |
552 |
|
|
553 |
|
private void updateCollectionFields(Session session, |
554 |
|
Object object, |
555 |
|
ClassDescriptor classDescriptor, |
556 |
|
Node objectNode) { |
557 |
0 |
Iterator collectionDescriptorIterator = classDescriptor.getCollectionDescriptors() |
558 |
|
.iterator(); |
559 |
0 |
while (collectionDescriptorIterator.hasNext()) { |
560 |
0 |
CollectionDescriptor collectionDescriptor = (CollectionDescriptor) |
561 |
|
collectionDescriptorIterator.next(); |
562 |
0 |
CollectionConverter collectionConverter = this.getCollectionConverter(session, collectionDescriptor); |
563 |
0 |
Object collection = ReflectionUtils.getNestedProperty(object, |
564 |
|
collectionDescriptor.getFieldName()); |
565 |
0 |
ManageableCollection manageableCollection = ManageableCollectionUtil |
566 |
|
.getManageableCollection(collection); |
567 |
0 |
collectionConverter.updateCollection(session, |
568 |
|
objectNode, |
569 |
|
collectionDescriptor, |
570 |
|
manageableCollection); |
571 |
|
} |
572 |
0 |
} |
573 |
|
|
574 |
|
private void storeSimpleFields(Session session, |
575 |
|
Object object, |
576 |
|
ClassDescriptor classDescriptor, |
577 |
|
Node objectNode) { |
578 |
|
try { |
579 |
0 |
ValueFactory valueFactory = session.getValueFactory(); |
580 |
|
|
581 |
0 |
Iterator fieldDescriptorIterator = classDescriptor.getFieldDescriptors().iterator(); |
582 |
0 |
while (fieldDescriptorIterator.hasNext()) { |
583 |
0 |
FieldDescriptor fieldDescriptor = (FieldDescriptor) fieldDescriptorIterator.next(); |
584 |
|
|
585 |
|
|
586 |
0 |
if (fieldDescriptor.isPath()) { |
587 |
0 |
continue; |
588 |
|
} |
589 |
|
|
590 |
|
|
591 |
0 |
if (classDescriptor.usesNodeTypePerHierarchyStrategy() && fieldDescriptor.isDiscriminator()) { |
592 |
0 |
if (null != classDescriptor.getDiscriminatorValue() && !"".equals(classDescriptor.getDiscriminatorValue())) { |
593 |
0 |
objectNode.setProperty(fieldDescriptor.getJcrName(), classDescriptor.getDiscriminatorValue()); |
594 |
|
} |
595 |
|
else { |
596 |
0 |
throw new PersistenceException("Cannot persist object of type " + object.getClass().getName() |
597 |
|
+ " Missing discriminator value from class descriptor."); |
598 |
|
} |
599 |
|
|
600 |
|
continue; |
601 |
|
} |
602 |
|
|
603 |
0 |
String fieldName = fieldDescriptor.getFieldName(); |
604 |
0 |
String jcrName = fieldDescriptor.getJcrName(); |
605 |
|
|
606 |
0 |
boolean protectedProperty= fieldDescriptor.isJcrProtected(); |
607 |
|
|
608 |
0 |
if(objectNode.hasProperty(jcrName)) { |
609 |
0 |
protectedProperty= objectNode.getProperty(jcrName).getDefinition().isProtected(); |
610 |
|
} |
611 |
|
|
612 |
0 |
if(!protectedProperty) { |
613 |
0 |
Object fieldValue = ReflectionUtils.getNestedProperty(object, fieldName); |
614 |
0 |
AtomicTypeConverter converter= getAtomicTypeConverter(fieldDescriptor, |
615 |
|
object, |
616 |
|
fieldName); |
617 |
0 |
Value value = converter.getValue(valueFactory, fieldValue); |
618 |
|
|
619 |
|
|
620 |
0 |
boolean autoCreated= fieldDescriptor.isJcrAutoCreated(); |
621 |
|
|
622 |
0 |
if(objectNode.hasProperty(jcrName)) { |
623 |
0 |
autoCreated= objectNode.getProperty(jcrName).getDefinition().isAutoCreated(); |
624 |
|
} |
625 |
|
|
626 |
0 |
if(!autoCreated) { |
627 |
|
|
628 |
0 |
checkMandatoryProperty(objectNode, fieldDescriptor, value); |
629 |
|
} |
630 |
|
|
631 |
0 |
objectNode.setProperty(jcrName, value); |
632 |
|
} |
633 |
|
} |
634 |
|
} |
635 |
0 |
catch(ValueFormatException vfe) { |
636 |
0 |
throw new PersistenceException("Cannot persist properties of object " + object |
637 |
|
+ ". Value format exception.", |
638 |
|
vfe); |
639 |
|
} |
640 |
0 |
catch(VersionException ve) { |
641 |
0 |
throw new PersistenceException("Cannot persist properties of object " + object |
642 |
|
+ ". Versioning exception.", |
643 |
|
ve); |
644 |
|
} |
645 |
0 |
catch(LockException le) { |
646 |
0 |
throw new PersistenceException("Cannot persist properties of object " + object |
647 |
|
+ " on locked node.", |
648 |
|
le); |
649 |
|
} |
650 |
0 |
catch(ConstraintViolationException cve) { |
651 |
0 |
throw new PersistenceException("Cannot persist properties of object " + object |
652 |
|
+ ". Constraint violation.", |
653 |
|
cve); |
654 |
|
} |
655 |
0 |
catch(RepositoryException re) { |
656 |
0 |
throw new org.apache.portals.graffito.jcr.exception.RepositoryException( |
657 |
|
"Cannot persist properties of object " + object, |
658 |
|
re); |
659 |
0 |
} |
660 |
0 |
} |
661 |
|
|
662 |
|
private CollectionConverter getCollectionConverter(Session session, CollectionDescriptor collectionDescriptor) { |
663 |
0 |
String className = collectionDescriptor.getCollectionConverterClassName(); |
664 |
0 |
Map atomicTypeConverters= this.atomicTypeConverterProvider.getAtomicTypeConverters(); |
665 |
0 |
if (className == null) { |
666 |
0 |
return new DefaultCollectionConverterImpl(atomicTypeConverters, this, class="keyword">this.mapper); |
667 |
|
} else { |
668 |
0 |
return (CollectionConverter) ReflectionUtils.invokeConstructor(className, |
669 |
|
new Object[] {atomicTypeConverters, this, class="keyword">this.mapper}); |
670 |
|
} |
671 |
|
|
672 |
|
} |
673 |
|
|
674 |
|
private void checkMandatoryProperty(Node objectNode, |
675 |
|
FieldDescriptor fieldDescriptor, |
676 |
|
Value value) throws RepositoryException { |
677 |
0 |
PropertyDefinition[] propertyDefinitions = objectNode.getPrimaryNodeType() |
678 |
|
.getDeclaredPropertyDefinitions(); |
679 |
0 |
for (int i = 0; i < propertyDefinitions.length; i++) { |
680 |
0 |
PropertyDefinition definition = propertyDefinitions[i]; |
681 |
0 |
if (definition.getName().equals(fieldDescriptor.getJcrName()) |
682 |
|
&& definition.isMandatory() |
683 |
|
&& (definition.isAutoCreated() == false) |
684 |
|
&& (value == null)) |
685 |
|
{ |
686 |
0 |
throw new PersistenceException("Class of type:" |
687 |
|
+ fieldDescriptor.getClassDescriptor().getClassName() |
688 |
|
+ " has property: " |
689 |
|
+ fieldDescriptor.getFieldName() |
690 |
|
+ " declared as JCR property: " |
691 |
|
+ fieldDescriptor.getJcrName() |
692 |
|
+ " This property is mandatory but property in bean has value null"); |
693 |
|
} |
694 |
|
} |
695 |
0 |
} |
696 |
|
|
697 |
|
private AtomicTypeConverter getAtomicTypeConverter(FieldDescriptor fd, |
698 |
|
Object object, |
699 |
|
String fieldName) { |
700 |
0 |
Class fieldTypeClass = null; |
701 |
0 |
if (null != fd.getFieldTypeClass()) { |
702 |
0 |
fieldTypeClass = fd.getFieldTypeClass(); |
703 |
|
} |
704 |
0 |
else if (null != object) { |
705 |
0 |
fieldTypeClass = ReflectionUtils.getPropertyType(object, fieldName); |
706 |
|
} |
707 |
|
|
708 |
0 |
if (null != fieldTypeClass) { |
709 |
0 |
return this.atomicTypeConverterProvider.getAtomicTypeConverter(fieldTypeClass); |
710 |
|
} |
711 |
|
else { |
712 |
0 |
return NULL_CONVERTER; |
713 |
|
} |
714 |
|
} |
715 |
|
|
716 |
|
protected ClassDescriptor getClassDescriptor(Class beanClass) { |
717 |
0 |
ClassDescriptor classDescriptor = mapper.getClassDescriptor(beanClass); |
718 |
0 |
if(null == classDescriptor) { |
719 |
0 |
throw new JcrMappingException("Class of type: " + beanClass.getName() |
720 |
|
+ " is not JCR persistable. Maybe element 'class-descriptor' for this type in mapping file is missing"); |
721 |
|
} |
722 |
|
|
723 |
0 |
if(classDescriptor.isAbstract()) { |
724 |
0 |
throw new PersistenceException("Cannot persist/retrieve abstract class " + beanClass.getName()); |
725 |
|
} |
726 |
|
|
727 |
0 |
return classDescriptor; |
728 |
|
} |
729 |
|
} |