Coverage report

  %line %branch
org.apache.portals.graffito.jcr.persistence.objectconverter.impl.ObjectConverterImpl
0% 
0% 

 1  
 /*
 2  
  * Copyright 2000-2005 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 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  
  * Default implementation for {@link ObjectConverterImpl}
 55  
  *
 56  
  * @author <a href="mailto:christophe.lombart@sword-technologies.com">Lombart Christophe </a>
 57  
  * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
 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  
      * No-arg constructor.
 68  
      */
 69  0
     public ObjectConverterImpl() {
 70  0
     }
 71  
 
 72  
     /**
 73  
      * Constructor
 74  
      *
 75  
      * @param mapper The mapper to used
 76  
      * @param converterProvider The atomic type converter provider
 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  
      * Set the <code>Mapper</code> used to solve mappings.
 86  
      * @param mapper a <code>Mapper</code>
 87  
      */
 88  
     public void setMapper(Mapper mapper) {
 89  0
         this.mapper = mapper;
 90  0
     }
 91  
 
 92  
     /**
 93  
      * Sets the converter provider.
 94  
      *
 95  
      * @param converterProvider an <code>AtomicTypeConverterProvider</code>
 96  
      */
 97  
     public void setAtomicTypeConverterProvider(AtomicTypeConverterProvider converterProvider) {
 98  0
         this.atomicTypeConverterProvider = converterProvider;
 99  0
     }
 100  
 
 101  
     /**
 102  
      * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#insert(javax.jcr.Session, java.lang.Object)
 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  
      * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#insert(javax.jcr.Session, javax.jcr.Node, java.lang.String, java.lang.Object)
 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  
      * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#update(javax.jcr.Session, java.lang.Object)
 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  
      * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#update(javax.jcr.Session, javax.jcr.Node, java.lang.String, java.lang.Object)
 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  
      * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#getObject(javax.jcr.Session, java.lang.Class, java.lang.String)
 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  
             // HINT should never get here
 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  
      * @see org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter#getPath(javax.jcr.Session, java.lang.Object)
 288  
      * @throws JcrMappingException
 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  
      * Retrieve simple fields (atomic fields)
 307  
      * 
 308  
      * @throws JcrMappingException
 309  
      * @throws org.apache.portals.graffito.jcr.exception.RepositoryException
 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) { // HINT: lazy initialize target bean
 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) { // HINT: lazy initialize target bean
 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  
      * Retrieve bean fields
 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  
      * Retrieve Collection fields
 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  
      * Insert Bean fields
 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  
      * Update Bean fields
 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  
                 // if the bean is null, remove existing node
 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  
                 //Of course, Path field is not updated as property
 586  0
                 if (fieldDescriptor.isPath()) {
 587  0
                     continue;
 588  
                 }
 589  
 
 590  
                 // Discriminator is already written
 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) { // DO NOT TRY TO WRITE PROTECTED PROPERTIES
 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  
                     // Check if the node property is "autocreated"
 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  
                         // Check if mandatory property are not null
 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  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.