Coverage Report - org.kuali.rice.kns.service.impl.PersistenceServiceJpaImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
PersistenceServiceJpaImpl
0%
0/145
0%
0/68
6.231
 
 1  
 /*
 2  
  * Copyright 2005-2008 The Kuali Foundation
 3  
  * 
 4  
  * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
 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.kuali.rice.kns.service.impl;
 17  
 
 18  
 import java.beans.PropertyDescriptor;
 19  
 import java.lang.reflect.Field;
 20  
 import java.lang.reflect.InvocationTargetException;
 21  
 import java.util.HashSet;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import java.util.Set;
 26  
 
 27  
 import org.apache.commons.beanutils.PropertyUtils;
 28  
 import org.apache.commons.lang.StringUtils;
 29  
 import org.apache.log4j.Logger;
 30  
 import org.kuali.rice.core.jpa.metadata.EntityDescriptor;
 31  
 import org.kuali.rice.core.jpa.metadata.MetadataManager;
 32  
 import org.kuali.rice.core.jpa.metadata.ObjectDescriptor;
 33  
 import org.kuali.rice.kns.bo.PersistableBusinessObject;
 34  
 import org.kuali.rice.kns.dao.PersistenceDao;
 35  
 import org.kuali.rice.kns.exception.IntrospectionException;
 36  
 import org.kuali.rice.kns.exception.ObjectNotABusinessObjectRuntimeException;
 37  
 import org.kuali.rice.kns.exception.ReferenceAttributeDoesntExistException;
 38  
 import org.kuali.rice.kns.exception.ReferenceAttributeNotAnOjbReferenceException;
 39  
 import org.kuali.rice.kns.service.PersistenceService;
 40  
 import org.kuali.rice.kns.util.ObjectUtils;
 41  
 import org.springframework.transaction.annotation.Transactional;
 42  
 
 43  
 
 44  
 /**
 45  
  * This class is the service implementation for the Persistence structure.
 46  
  */
 47  
 @Transactional
 48  0
 public class PersistenceServiceJpaImpl extends PersistenceServiceImplBase implements PersistenceService {
 49  
 
 50  0
         private static Logger LOG = Logger.getLogger(PersistenceServiceJpaImpl.class);
 51  
     private PersistenceDao persistenceDao;
 52  
         
 53  
     public void setPersistenceDao(PersistenceDao persistenceDao) {
 54  0
         this.persistenceDao = persistenceDao;
 55  0
     }
 56  
 
 57  
         /**
 58  
          * @see org.kuali.rice.kns.service.PersistenceService#allForeignKeyValuesPopulatedForReference(org.kuali.rice.kns.bo.PersistableBusinessObject, java.lang.String)
 59  
          */
 60  
         public boolean allForeignKeyValuesPopulatedForReference(PersistableBusinessObject bo, String referenceName) {
 61  0
         boolean allFkeysHaveValues = true;
 62  
 
 63  
         // yelp if nulls were passed in
 64  0
         if (bo == null) {
 65  0
             throw new IllegalArgumentException("The Class passed in for the BusinessObject argument was null.");
 66  
         }
 67  0
         if (StringUtils.isBlank(referenceName)) {
 68  0
             throw new IllegalArgumentException("The String passed in for the referenceName argument was null or empty.");
 69  
         }
 70  
 
 71  0
         PropertyDescriptor propertyDescriptor = null;
 72  
 
 73  
         // make sure the attribute exists at all, throw exception if not
 74  
         try {
 75  0
             propertyDescriptor = PropertyUtils.getPropertyDescriptor(bo, referenceName);
 76  0
                 } catch (Exception e) {
 77  0
             throw new RuntimeException(e);
 78  0
         }
 79  0
         if (propertyDescriptor == null) {
 80  0
             throw new ReferenceAttributeDoesntExistException("Requested attribute: '" + referenceName + "' does not exist " + "on class: '" + bo.getClass().getName() + "'.");
 81  
         }
 82  
 
 83  
         // get the class of the attribute name
 84  0
         Class referenceClass = getBusinessObjectAttributeClass( bo.getClass(), referenceName );
 85  0
         if ( referenceClass == null ) {
 86  0
                 referenceClass = propertyDescriptor.getPropertyType();
 87  
         }
 88  
 
 89  
         // make sure the class of the attribute descends from BusinessObject,
 90  
         // otherwise throw an exception
 91  0
         if (!PersistableBusinessObject.class.isAssignableFrom(referenceClass)) {
 92  0
                         throw new ObjectNotABusinessObjectRuntimeException("Attribute requested (" + referenceName + ") is of class: " + "'" + referenceClass.getName() + "' and is not a " + "descendent of BusinessObject.  Only descendents of BusinessObject " + "can be used.");
 93  
         }
 94  
 
 95  0
         EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(bo.getClass());
 96  0
             ObjectDescriptor objectDescriptor = descriptor.getObjectDescriptorByName(referenceName);
 97  0
         if (objectDescriptor == null) {
 98  0
             throw new ReferenceAttributeNotAnOjbReferenceException("Attribute requested (" + referenceName + ") is not listed " + "in OJB as a reference-descriptor for class: '" + bo.getClass().getName() + "'");
 99  
         }
 100  
 
 101  
                 // get the list of the foreign-keys for this reference-descriptor
 102  0
         List fkFields = objectDescriptor.getForeignKeyFields();
 103  0
         Iterator fkIterator = fkFields.iterator();
 104  
 
 105  
         // walk through the list of the foreign keys, get their types
 106  0
         while (fkIterator.hasNext()) {
 107  
 
 108  
             // get the field name of the fk & pk field
 109  0
             String fkFieldName = (String) fkIterator.next();
 110  
 
 111  
             // get the value for the fk field
 112  0
             Object fkFieldValue = null;
 113  
             try {
 114  0
                 fkFieldValue = PropertyUtils.getSimpleProperty(bo, fkFieldName);
 115  
             }
 116  
 
 117  
             // if we cant retrieve the field value, then
 118  
             // it doesnt have a value
 119  0
             catch (IllegalAccessException e) {
 120  0
                 return false;
 121  0
                         } catch (InvocationTargetException e) {
 122  0
                 return false;
 123  0
                         } catch (NoSuchMethodException e) {
 124  0
                 return false;
 125  0
             }
 126  
 
 127  
             // test the value
 128  0
             if (fkFieldValue == null) {
 129  0
                 return false;
 130  0
                         } else if (String.class.isAssignableFrom(fkFieldValue.getClass())) {
 131  0
                 if (StringUtils.isBlank((String) fkFieldValue)) {
 132  0
                     return false;
 133  
                 }
 134  
             }
 135  0
         }
 136  
         
 137  0
         return allFkeysHaveValues;
 138  
     }
 139  
 
 140  
         /**
 141  
          * @see org.kuali.rice.kns.service.PersistenceService#clearCache()
 142  
          */
 143  
         public void clearCache() {
 144  0
                 persistenceDao.clearCache();
 145  0
         }
 146  
 
 147  
         /**
 148  
          * @see org.kuali.rice.kns.service.PersistenceService#getFlattenedPrimaryKeyFieldValues(java.lang.Object)
 149  
          */
 150  
         public String getFlattenedPrimaryKeyFieldValues(Object persistableObject) {
 151  0
         if (persistableObject == null) {
 152  0
             throw new IllegalArgumentException("invalid (null) persistableObject");
 153  
         }
 154  
         
 155  0
         Map primaryKeyValues = getPrimaryKeyFieldValues(persistableObject, true);
 156  
 
 157  0
         StringBuffer flattened = new StringBuffer(persistableObject.getClass().getName());
 158  0
         flattened.append("(");
 159  0
         for (Iterator i = primaryKeyValues.entrySet().iterator(); i.hasNext();) {
 160  0
             Map.Entry e = (Map.Entry) i.next();
 161  
 
 162  0
             String fieldName = (String) e.getKey();
 163  0
             Object fieldValue = e.getValue();
 164  
 
 165  0
             flattened.append(fieldName + "=" + fieldValue);
 166  0
             if (i.hasNext()) {
 167  0
                 flattened.append(",");
 168  
             }
 169  0
         }
 170  
 
 171  0
         flattened.append(")");
 172  
 
 173  0
         return flattened.toString();
 174  
         }
 175  
 
 176  
         /**
 177  
          * @see org.kuali.rice.kns.service.PersistenceService#linkObjects(java.lang.Object)
 178  
          */
 179  
         public void linkObjects(Object persistableObject) {
 180  0
                 linkObjectsWithCircularReferenceCheck(persistableObject, new HashSet());
 181  0
         }
 182  
 
 183  
         /**
 184  
          * @see org.kuali.rice.kns.service.PersistenceService#loadRepositoryDescriptor(java.lang.String)
 185  
          */
 186  0
         public void loadRepositoryDescriptor(String ojbRepositoryFilePath) {}
 187  
 
 188  
         /**
 189  
          * @see org.kuali.rice.kns.service.PersistenceService#refreshAllNonUpdatingReferences(org.kuali.rice.kns.bo.PersistableBusinessObject)
 190  
          */
 191  
         public void refreshAllNonUpdatingReferences(PersistableBusinessObject bo) {
 192  0
                 EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(bo.getClass());
 193  0
                 List<ObjectDescriptor> objectDescriptors = descriptor.getObjectRelationships();
 194  
                 
 195  0
                 for (ObjectDescriptor od : objectDescriptors) {
 196  0
             if (od.getCascade().length == 0) {                   
 197  0
                 retrieveReferenceObject(bo, od.getAttributeName());
 198  
             }                        
 199  
                 }
 200  0
     }
 201  
 
 202  
         /**
 203  
          * @see org.kuali.rice.kns.service.PersistenceService#resolveProxy(java.lang.Object)
 204  
          */
 205  
         public Object resolveProxy(Object o) {
 206  0
                 return persistenceDao.resolveProxy(o);
 207  
         }
 208  
 
 209  
         /**
 210  
          * @see org.kuali.rice.kns.service.PersistenceService#retrieveNonKeyFields(java.lang.Object)
 211  
          */
 212  
         public void retrieveNonKeyFields(Object persistableObject) {
 213  0
         if (persistableObject == null) {
 214  0
             throw new IllegalArgumentException("invalid (null) persistableObject");
 215  
         }
 216  0
         LOG.debug("retrieving non-key fields for " + persistableObject);
 217  
 
 218  0
         persistenceDao.retrieveAllReferences(persistableObject);
 219  0
     }
 220  
 
 221  
         /**
 222  
          * @see org.kuali.rice.kns.service.PersistenceService#retrieveReferenceObject(java.lang.Object, java.lang.String)
 223  
          */
 224  
         public void retrieveReferenceObject(Object persistableObject, String referenceObjectName) {
 225  0
         if (persistableObject == null) {
 226  0
             throw new IllegalArgumentException("invalid (null) persistableObject");
 227  
         }
 228  0
         LOG.debug("retrieving reference object " + referenceObjectName + " for " + persistableObject);
 229  
 
 230  0
         persistenceDao.retrieveReference(persistableObject, referenceObjectName);
 231  0
     }
 232  
 
 233  
         /**
 234  
          * @see org.kuali.rice.kns.service.PersistenceService#retrieveReferenceObjects(java.lang.Object, java.util.List)
 235  
          */
 236  
         public void retrieveReferenceObjects(Object persistableObject, List referenceObjectNames) {
 237  0
         if (persistableObject == null) {
 238  0
             throw new IllegalArgumentException("invalid (null) persistableObject");
 239  
         }
 240  0
         if (referenceObjectNames == null) {
 241  0
             throw new IllegalArgumentException("invalid (null) referenceObjectNames");
 242  
         }
 243  0
         if (referenceObjectNames.isEmpty()) {
 244  0
             throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
 245  
         }
 246  
 
 247  0
         int index = 0;
 248  0
         for (Iterator i = referenceObjectNames.iterator(); i.hasNext(); index++) {
 249  0
             String referenceObjectName = (String) i.next();
 250  0
             if (StringUtils.isBlank(referenceObjectName)) {
 251  0
                 throw new IllegalArgumentException("invalid (blank) name at position " + index);
 252  
             }
 253  
 
 254  0
             retrieveReferenceObject(persistableObject, referenceObjectName);
 255  
         }
 256  0
         }
 257  
 
 258  
         /**
 259  
          * @see org.kuali.rice.kns.service.PersistenceService#retrieveReferenceObjects(java.util.List, java.util.List)
 260  
          */
 261  
         public void retrieveReferenceObjects(List persistableObjects, List referenceObjectNames) {
 262  0
         if (persistableObjects == null) {
 263  0
             throw new IllegalArgumentException("invalid (null) persistableObjects");
 264  
         }
 265  0
         if (persistableObjects.isEmpty()) {
 266  0
             throw new IllegalArgumentException("invalid (empty) persistableObjects");
 267  
         }
 268  0
         if (referenceObjectNames == null) {
 269  0
             throw new IllegalArgumentException("invalid (null) referenceObjectNames");
 270  
         }
 271  0
         if (referenceObjectNames.isEmpty()) {
 272  0
             throw new IllegalArgumentException("invalid (empty) referenceObjectNames");
 273  
         }
 274  
 
 275  0
         for (Iterator i = persistableObjects.iterator(); i.hasNext();) {
 276  0
             Object persistableObject = i.next();
 277  0
             retrieveReferenceObjects(persistableObject, referenceObjectNames);
 278  0
         }
 279  0
         }
 280  
     
 281  
     private void linkObjectsWithCircularReferenceCheck(Object persistableObject, Set referenceSet) {
 282  0
         if (ObjectUtils.isNull(persistableObject) || referenceSet.contains(persistableObject)) {
 283  0
             return;
 284  
         }
 285  
         
 286  0
         referenceSet.add(persistableObject);
 287  
         
 288  0
         EntityDescriptor descriptor = MetadataManager.getEntityDescriptor(persistableObject.getClass());
 289  
 
 290  0
         String className = null;
 291  0
         String fieldName = null;
 292  
         try {
 293  
             // iterate through all object references for the persistableObject
 294  0
                 List<ObjectDescriptor> objectDescriptors = descriptor.getObjectRelationships();
 295  0
                 for (ObjectDescriptor od : objectDescriptors) {
 296  
                 // get the actual reference object
 297  0
                 className = persistableObject.getClass().getName();
 298  0
                 fieldName = od.getAttributeName();
 299  0
                 Object referenceObject = PropertyUtils.getProperty(persistableObject, fieldName);
 300  0
                 if (ObjectUtils.isNull(referenceObject) || referenceSet.contains(referenceObject)) {
 301  0
                     continue;
 302  
                 }
 303  
 
 304  
                 // recursively link object
 305  0
                 linkObjectsWithCircularReferenceCheck(referenceObject, referenceSet);
 306  
 
 307  
                                 // iterate through the keys for the reference object and set value
 308  0
                 List<String> refFkNames = od.getForeignKeyFields();
 309  0
                 EntityDescriptor refCld = MetadataManager.getEntityDescriptor(od.getTargetEntity());
 310  0
                 Set<org.kuali.rice.core.jpa.metadata.FieldDescriptor> refPkNames = refCld.getPrimaryKeys();
 311  
 
 312  
                 try {
 313  0
                         for (String fk : refFkNames) {
 314  0
                                                 Field f = referenceObject.getClass().getDeclaredField(fk);
 315  0
                                                 f.setAccessible(true);
 316  0
                                 if (ObjectUtils.isNull(f.get(referenceObject))) {
 317  0
                                                         Field f2 = persistableObject.getClass().getDeclaredField(fk);
 318  0
                                                         f2.setAccessible(true);
 319  0
                                                         f.set(referenceObject, f2.get(persistableObject));
 320  
                                                 }                                
 321  0
                                         }
 322  0
                 } catch (Exception e) {
 323  0
                         LOG.error(e.getMessage(), e);
 324  0
                 }
 325  0
             }
 326  0
                 } catch (NoSuchMethodException e) {
 327  0
             throw new IntrospectionException("no setter for property '" + className + "." + fieldName + "'", e);
 328  0
                 } catch (IllegalAccessException e) {
 329  0
             throw new IntrospectionException("problem accessing property '" + className + "." + fieldName + "'", e);
 330  0
                 } catch (InvocationTargetException e) {
 331  0
             throw new IntrospectionException("problem invoking getter for property '" + className + "." + fieldName + "'", e);
 332  0
         }
 333  0
     }
 334  
     
 335  
 }