Coverage report

  %line %branch
org.apache.portals.graffito.jcr.persistence.collectionconverter.impl.NTCollectionConverterImpl
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  
 
 17  
 package org.apache.portals.graffito.jcr.persistence.collectionconverter.impl;
 18  
 
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.HashMap;
 23  
 import java.util.Iterator;
 24  
 import java.util.List;
 25  
 import java.util.Map;
 26  
 
 27  
 import javax.jcr.Node;
 28  
 import javax.jcr.NodeIterator;
 29  
 import javax.jcr.PathNotFoundException;
 30  
 import javax.jcr.RepositoryException;
 31  
 import javax.jcr.Session;
 32  
 import javax.jcr.ValueFormatException;
 33  
 import javax.jcr.lock.LockException;
 34  
 import javax.jcr.nodetype.ConstraintViolationException;
 35  
 import javax.jcr.version.VersionException;
 36  
 
 37  
 import org.apache.commons.logging.Log;
 38  
 import org.apache.commons.logging.LogFactory;
 39  
 import org.apache.portals.graffito.jcr.mapper.Mapper;
 40  
 import org.apache.portals.graffito.jcr.mapper.model.ClassDescriptor;
 41  
 import org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor;
 42  
 import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollection;
 43  
 import org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollectionUtil;
 44  
 import org.apache.portals.graffito.jcr.persistence.objectconverter.ObjectConverter;
 45  
 import org.apache.portals.graffito.jcr.reflection.ReflectionUtils;
 46  
 
 47  
 /**
 48  
  * Collection Mapping/convertion based on node type.
 49  
  *
 50  
  * This collection mapping strategy maps a collection into several nodes based on specific node type.
 51  
  *
 52  
  *
 53  
  * If the collection element class contains an id (see the FieldDescriptor definition), this id value is used to build the collection element node.
 54  
  * Otherwise, the element node name is a simple indexed constant.
 55  
  *
 56  
  * Example - without an id attribute:
 57  
  *   /test (Main object containing the collection field )
 58  
  *          /collection-element1 (node used to store the first collection element)
 59  
  *                /item-prop
 60  
  *                ....
 61  
  *          /collection-element2 (node used to store the second collection element)
 62  
  *          ...
 63  
  *
 64  
  * Example - with an id attribute:
 65  
  *   /test (Main object containing the collection field )
 66  
  *          /aValue (id value assigned to the first element)
 67  
  *                /item-prop
 68  
  *                ....
 69  
  *          /anotherValue (id value assigned to the first element)
 70  
  *          ...
 71  
  *
 72  
  * @author <a href="mailto:christophe.lombart@gmail.com">Christophe Lombart</a>
 73  
  *
 74  
  */
 75  
 public class NTCollectionConverterImpl extends AbstractCollectionConverterImpl {
 76  
 
 77  0
     private final static Log log = LogFactory.getLog(NTCollectionConverterImpl.class);
 78  
 
 79  
     private static final String COLLECTION_ELEMENT_NAME = "collection-element";
 80  
 
 81  
     /**
 82  
      * Constructor
 83  
      *
 84  
      * @param atomicTypeConverters
 85  
      * @param objectConverter
 86  
      * @param mapper
 87  
      */
 88  
     public NTCollectionConverterImpl(Map atomicTypeConverters,
 89  
                                      ObjectConverter objectConverter,
 90  
                                      Mapper mapper) {
 91  0
         super(atomicTypeConverters, objectConverter, mapper);
 92  0
     }
 93  
 
 94  
     /**
 95  
      * @see AbstractCollectionConverterImpl#doInsertCollection(Session, Node, CollectionDescriptor, ManageableCollection)
 96  
      */
 97  
     protected void doInsertCollection(Session session,
 98  
                                       Node parentNode,
 99  
                                       CollectionDescriptor collectionDescriptor,
 100  
                                       ManageableCollection collection) {
 101  0
         if (collection == null) {
 102  0
             return;
 103  
         }
 104  
 
 105  0
         Mapper mapper = collectionDescriptor.getClassDescriptor().getMappingDescriptor().getMapper();
 106  0
         ClassDescriptor elementClassDescriptor = mapper.getClassDescriptor(
 107  
                 ReflectionUtils.forName(collectionDescriptor.getElementClassName()));
 108  
 
 109  0
         Iterator collectionIterator = collection.getIterator();
 110  0
         int elementCollectionCount = 0;
 111  0
         while (collectionIterator.hasNext()) {
 112  0
             Object item = collectionIterator.next();
 113  0
             String elementJcrName = null;
 114  
 
 115  
             // If the element object has a unique id => the element jcr node name = the id value
 116  0
             if (elementClassDescriptor.hasIdField()) {
 117  0
                 String idFieldName = elementClassDescriptor.getIdFieldDescriptor().getFieldName();
 118  0
                 elementJcrName = ReflectionUtils.getNestedProperty(item, idFieldName).toString();
 119  
             }
 120  
             else {
 121  0
                 elementCollectionCount++;
 122  0
                 elementJcrName = COLLECTION_ELEMENT_NAME + elementCollectionCount;
 123  
             }
 124  
 
 125  0
             objectConverter.insert(session, parentNode, elementJcrName, item);
 126  
         }
 127  0
     }
 128  
 
 129  
     /**
 130  
      *
 131  
      * @see org.apache.portals.graffito.jcr.persistence.collectionconverter.CollectionConverter#updateCollection(javax.jcr.Session, javax.jcr.Node, org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor, org.apache.portals.graffito.jcr.persistence.collectionconverter.ManageableCollection)
 132  
      */
 133  
     protected void doUpdateCollection(Session session,
 134  
                                       Node parentNode,
 135  
                                       CollectionDescriptor collectionDescriptor,
 136  
                                       ManageableCollection collection) throws RepositoryException {
 137  0
         Mapper mapper = collectionDescriptor.getClassDescriptor().getMappingDescriptor().getMapper();
 138  0
         ClassDescriptor elementClassDescriptor = mapper.getClassDescriptor(
 139  
                 ReflectionUtils.forName(collectionDescriptor.getElementClassName()));
 140  
 
 141  0
         if (collection == null || !elementClassDescriptor.hasIdField()) {
 142  0
             this.deleteCollectionItems(session,
 143  
                                        parentNode,
 144  
                                        elementClassDescriptor.getJcrNodeType());
 145  
         }
 146  
 
 147  0
         if (collection == null) {
 148  0
             return;
 149  
         }
 150  
 
 151  0
         Iterator collectionIterator = collection.getIterator();
 152  0
         int elementCollectionCount = 0;
 153  
 
 154  0
         Map updatedItems = new HashMap();
 155  0
         while (collectionIterator.hasNext()) {
 156  0
             Object item = collectionIterator.next();
 157  
 
 158  0
             elementCollectionCount++;
 159  0
             String elementJcrName = null;
 160  
 
 161  0
             if (elementClassDescriptor.hasIdField()) {
 162  0
                 String idFieldName = elementClassDescriptor.getIdFieldDescriptor().getFieldName();
 163  0
                 elementJcrName = ReflectionUtils.getNestedProperty(item, idFieldName).toString();
 164  
 
 165  
                 // Update existing JCR Nodes
 166  0
                 if (parentNode.hasNode(elementJcrName)) {
 167  0
                     objectConverter.update(session, parentNode, elementJcrName, item);
 168  
                 }
 169  
                 else {
 170  
                     // Add new collection elements
 171  0
                     objectConverter.insert(session, parentNode, elementJcrName, item);
 172  
                 }
 173  
 
 174  0
                 updatedItems.put(elementJcrName, item);
 175  
             }
 176  
             else {
 177  0
                 elementJcrName = COLLECTION_ELEMENT_NAME + elementCollectionCount;
 178  0
                 objectConverter.insert(session, parentNode, elementJcrName, item);
 179  
             }
 180  
         }
 181  
 
 182  
         // Delete JCR nodes that are not present in the collection
 183  0
         if (elementClassDescriptor.hasIdField()) {
 184  0
             Iterator nodeIterator = this.getCollectionNodes(session, parentNode,
 185  
                     elementClassDescriptor.getJcrNodeType()).iterator();
 186  
 
 187  0
             while (nodeIterator.hasNext()) {
 188  0
                 Node child = (Node) nodeIterator.next();
 189  
                 
 190  0
                 if (!updatedItems.containsKey(child.getName())) {
 191  0
                     child.remove();
 192  
                 }
 193  
             }
 194  
         }
 195  0
     }
 196  
 
 197  
     /**
 198  
      * @see org.apache.portals.graffito.jcr.persistence.collectionconverter.CollectionConverter#getCollection(javax.jcr.Session, javax.jcr.Node, org.apache.portals.graffito.jcr.mapper.model.CollectionDescriptor, java.lang.Class)
 199  
      */
 200  
     protected ManageableCollection doGetCollection(Session session,
 201  
                                                    Node parentNode,
 202  
                                                    CollectionDescriptor collectionDescriptor,
 203  
                                                    Class collectionFieldClass) throws RepositoryException {
 204  0
         Mapper mapper = collectionDescriptor.getClassDescriptor().getMappingDescriptor().getMapper();
 205  0
         ClassDescriptor elementClassDescriptor = mapper.getClassDescriptor(
 206  
                 ReflectionUtils.forName(collectionDescriptor.getElementClassName()));
 207  0
         ManageableCollection collection = ManageableCollectionUtil.getManageableCollection(collectionFieldClass);
 208  0
         Class elementClass = ReflectionUtils.forName(collectionDescriptor.getElementClassName());
 209  0
         Iterator children = this.getCollectionNodes(session, parentNode,
 210  
                 elementClassDescriptor.getJcrNodeType()).iterator();
 211  
 
 212  0
         while (children.hasNext()) {
 213  0
             Node itemNode = (Node) children.next();
 214  0
             log.debug("Collection node found : " + itemNode.getPath());
 215  0
             Object item = objectConverter.getObject(session, elementClass, itemNode.getPath());
 216  0
             collection.addObject(item);
 217  
         }
 218  
 
 219  0
         return collection;
 220  
     }
 221  
 
 222  
     private Collection getCollectionNodes(Session session, Node parentNode, String itemNodeType)
 223  
     throws PathNotFoundException, ValueFormatException, RepositoryException {
 224  
 
 225  0
         List collectionNodes = new ArrayList();
 226  
 
 227  
         // TODO : review this workaround used to support version nodes
 228  
         // Searching on the version storage has some bugs => loop on all child noded and check the property jcr:frozenPrimaryType
 229  
         // I have to investigate in more detail what's happen exactly
 230  0
         if (!parentNode.getPath().startsWith("/jcr:system/jcr:versionStorage")) {
 231  0
             NodeIterator nodeIterator = parentNode.getNodes();
 232  0
             while (nodeIterator.hasNext()) {
 233  0
                 Node child = nodeIterator.nextNode();
 234  
 
 235  0
                 if (child.isNodeType(itemNodeType)) {
 236  0
                     collectionNodes.add(child);
 237  
                 }
 238  
             }
 239  
         }
 240  
         else {
 241  0
             NodeIterator nodeIterator = parentNode.getNodes();
 242  0
             while (nodeIterator.hasNext()) {
 243  0
                 Node child = nodeIterator.nextNode();
 244  
 
 245  0
                 if (child.getProperty("jcr:frozenPrimaryType").getString().equals(itemNodeType)) {
 246  0
                     collectionNodes.add(child);
 247  
                 }
 248  
             }
 249  
 
 250  
         }
 251  
 
 252  0
         return collectionNodes;
 253  
     }
 254  
 
 255  
     private void deleteCollectionItems(Session session, Node parentNode, String itemNodeType) 
 256  
     throws VersionException, 
 257  
            LockException, 
 258  
            ConstraintViolationException, 
 259  
            PathNotFoundException, 
 260  
            ValueFormatException, 
 261  
            RepositoryException
 262  
     {
 263  0
         Iterator nodeIterator = this.getCollectionNodes(session, parentNode, itemNodeType).iterator();
 264  0
         while (nodeIterator.hasNext()) {
 265  0
             Node node = (Node) nodeIterator.next();
 266  0
             node.remove();
 267  
         }
 268  0
     }
 269  
 }

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