Coverage Report - org.kuali.rice.kns.service.impl.BusinessObjectMetaDataServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
BusinessObjectMetaDataServiceImpl
0%
0/233
0%
0/194
4.656
 
 1  
 /*
 2  
  * Copyright 2007 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.lang.reflect.InvocationTargetException;
 19  
 import java.util.ArrayList;
 20  
 import java.util.Collection;
 21  
 import java.util.HashMap;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 
 26  
 import org.apache.commons.lang.StringUtils;
 27  
 import org.kuali.rice.kns.bo.BusinessObject;
 28  
 import org.kuali.rice.kns.bo.BusinessObjectRelationship;
 29  
 import org.kuali.rice.kns.bo.PersistableBusinessObject;
 30  
 import org.kuali.rice.kns.datadictionary.DataDictionaryEntry;
 31  
 import org.kuali.rice.kns.datadictionary.FieldDefinition;
 32  
 import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
 33  
 import org.kuali.rice.kns.datadictionary.PrimitiveAttributeDefinition;
 34  
 import org.kuali.rice.kns.datadictionary.RelationshipDefinition;
 35  
 import org.kuali.rice.kns.datadictionary.SupportAttributeDefinition;
 36  
 import org.kuali.rice.kns.lookup.valueFinder.ValueFinder;
 37  
 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
 38  
 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
 39  
 import org.kuali.rice.kns.service.DataDictionaryService;
 40  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 41  
 import org.kuali.rice.kns.service.KualiModuleService;
 42  
 import org.kuali.rice.kns.service.ModuleService;
 43  
 import org.kuali.rice.kns.service.PersistenceStructureService;
 44  
 import org.kuali.rice.kns.util.ObjectUtils;
 45  
 
 46  
 /**
 47  
  *
 48  
  * Implementation of the <code>BusinessObjectMetaDataService</code> which uses
 49  
  * the following services to gather its meta data:
 50  
  *
 51  
  * @see BusinessObjectDictionaryService
 52  
  * @see DataDictionaryService
 53  
  * @see PersistenceStructureService
 54  
  */
 55  0
 public class BusinessObjectMetaDataServiceImpl implements BusinessObjectMetaDataService {
 56  0
         private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger .getLogger(BusinessObjectMetaDataServiceImpl.class);
 57  
 
 58  
         private BusinessObjectDictionaryService businessObjectDictionaryService;
 59  
         private DataDictionaryService dataDictionaryService;
 60  
         private PersistenceStructureService persistenceStructureService;
 61  
         private KualiModuleService kualiModuleService;
 62  
 
 63  
         public Collection<String> getCollectionNames(BusinessObject bo) {
 64  0
                 return dataDictionaryService.getDataDictionary()
 65  
                                 .getBusinessObjectEntry(bo.getClass().getName())
 66  
                                 .getCollectionNames();
 67  
         }
 68  
 
 69  
         public Collection<String> getInquirableFieldNames(Class boClass,
 70  
                         String sectionTitle) {
 71  0
                 return businessObjectDictionaryService.getInquiryFieldNames(boClass,
 72  
                                 sectionTitle);
 73  
         }
 74  
 
 75  
         public List<String> getLookupableFieldNames(Class boClass) {
 76  0
                 return businessObjectDictionaryService.getLookupFieldNames(boClass);
 77  
         }
 78  
 
 79  
         public String getLookupFieldDefaultValue(Class businessObjectClass,
 80  
                         String attributeName) {
 81  0
                 return businessObjectDictionaryService.getLookupFieldDefaultValue(
 82  
                                 businessObjectClass, attributeName);
 83  
         }
 84  
 
 85  
         public Class getLookupFieldDefaultValueFinderClass(
 86  
                         Class businessObjectClass, String attributeName) {
 87  0
                 return businessObjectDictionaryService
 88  
                                 .getLookupFieldDefaultValueFinderClass(businessObjectClass,
 89  
                                                 attributeName);
 90  
         }
 91  
 
 92  
         /** {@inheritDoc} */
 93  
         public String getLookupFieldQuickfinderParameterString(Class businessObjectClass,
 94  
                         String attributeName) {
 95  0
                 return businessObjectDictionaryService.getLookupFieldQuickfinderParameterString(
 96  
                                 businessObjectClass, attributeName);
 97  
         }
 98  
 
 99  
         /** {@inheritDoc} */
 100  
         public Class<? extends ValueFinder> getLookupFieldQuickfinderParameterStringBuilderClass(
 101  
                         Class businessObjectClass, String attributeName) {
 102  0
                 return businessObjectDictionaryService
 103  
                                 .getLookupFieldQuickfinderParameterStringBuilderClass(businessObjectClass,
 104  
                                                 attributeName);
 105  
         }
 106  
 
 107  
         public boolean isAttributeInquirable(Class boClass, String attributeName,
 108  
                         String sectionTitle) {
 109  0
                 Collection sections = businessObjectDictionaryService
 110  
                                 .getInquirySections(boClass);
 111  0
                 boolean isInquirable = true;
 112  
 
 113  0
                 Iterator iter = sections.iterator();
 114  
 
 115  0
                 while (iter.hasNext()) {
 116  0
                         InquirySectionDefinition def = (InquirySectionDefinition) iter
 117  
                                         .next();
 118  0
                         for (FieldDefinition field : def.getInquiryFields()) {
 119  0
                                 if (field.getAttributeName().equalsIgnoreCase(attributeName)) {
 120  0
                                         isInquirable = !field.isNoInquiry();
 121  
                                 }
 122  
                         }
 123  0
                 }
 124  0
                 if (isInquirable) {
 125  0
                         Object obj = null;
 126  0
                         if (boClass != null
 127  
                                         && BusinessObject.class.isAssignableFrom(boClass)) {
 128  0
                                 obj = ObjectUtils.createNewObjectFromClass(boClass);
 129  
                         }
 130  
 
 131  0
                         if (obj != null) {
 132  0
                                 BusinessObject bo = (BusinessObject) obj;
 133  0
                                 Class clazz = getNestedBOClass(bo, attributeName);
 134  0
                                 if (clazz != null
 135  
                                                 && BusinessObject.class.isAssignableFrom(clazz)) {
 136  0
                                         return businessObjectDictionaryService.isInquirable(clazz);
 137  
                                 } else {
 138  0
                                         return false;
 139  
                                 }
 140  
                         } else {
 141  0
                                 return false;
 142  
                         }
 143  
 
 144  
                 }
 145  
 
 146  0
                 return isInquirable;
 147  
         }
 148  
 
 149  
         public boolean isInquirable(Class boClass) {
 150  0
                 boolean inquirable = false;
 151  0
                 ModuleService moduleService = kualiModuleService
 152  
                                 .getResponsibleModuleService(boClass);
 153  0
                 if (moduleService != null && moduleService.isExternalizable(boClass)) {
 154  0
                         inquirable = moduleService
 155  
                                         .isExternalizableBusinessObjectInquirable(boClass);
 156  
                 } else {
 157  0
                         Boolean isLookupable = businessObjectDictionaryService
 158  
                                         .isInquirable(boClass);
 159  0
                         if (isLookupable != null) {
 160  0
                                 inquirable = isLookupable.booleanValue();
 161  
                         }
 162  
                 }
 163  0
                 return inquirable;
 164  
         }
 165  
 
 166  
         public boolean isAttributeLookupable(Class boClass, String attributeName) {
 167  0
                 Object obj = null;
 168  0
                 if (boClass != null && BusinessObject.class.isAssignableFrom(boClass)) {
 169  0
                         obj = ObjectUtils.createNewObjectFromClass(boClass);
 170  
                 }
 171  0
                 if (obj != null) {
 172  0
                         BusinessObject bo = (BusinessObject) obj;
 173  0
                         BusinessObjectRelationship relationship = getBusinessObjectRelationship(
 174  
                                         bo, attributeName);
 175  
 
 176  0
                         if (relationship != null
 177  
                                         && relationship.getRelatedClass() != null
 178  
                                         && BusinessObject.class.isAssignableFrom(relationship
 179  
                                                         .getRelatedClass())) {
 180  0
                                 return isLookupable(relationship.getRelatedClass());
 181  
                         } else {
 182  0
                                 return false;
 183  
                         }
 184  
                 } else {
 185  0
                         return false;
 186  
                 }
 187  
         }
 188  
 
 189  
         public boolean isLookupable(Class boClass) {
 190  0
                 boolean lookupable = false;
 191  0
                 ModuleService moduleService = kualiModuleService
 192  
                                 .getResponsibleModuleService(boClass);
 193  0
                 if (moduleService != null && moduleService.isExternalizable(boClass)) {
 194  0
                         lookupable = moduleService
 195  
                                         .isExternalizableBusinessObjectLookupable(boClass);
 196  
                 } else {
 197  0
                         Boolean isLookupable = businessObjectDictionaryService
 198  
                                         .isLookupable(boClass);
 199  0
                         if (isLookupable != null) {
 200  0
                                 lookupable = isLookupable.booleanValue();
 201  
                         }
 202  
                 }
 203  0
                 return lookupable;
 204  
         }
 205  
 
 206  
         public BusinessObjectRelationship getBusinessObjectRelationship(
 207  
                         BusinessObject bo, String attributeName) {
 208  0
                 return getBusinessObjectRelationship(bo, bo.getClass(), attributeName,
 209  
                                 "", true);
 210  
         }
 211  
         //TODO: four different exit points?!
 212  
         public BusinessObjectRelationship getBusinessObjectRelationship(
 213  
                         RelationshipDefinition ddReference, BusinessObject bo,
 214  
                         Class boClass, String attributeName, String attributePrefix,
 215  
                         boolean keysOnly) {
 216  
 
 217  0
                 BusinessObjectRelationship relationship = null;
 218  
 
 219  
                 // if it is nested then replace the bo and attributeName with the
 220  
                 // sub-refs
 221  0
                 if (ObjectUtils.isNestedAttribute(attributeName)) {
 222  0
                         if (ddReference != null) {
 223  0
                                 relationship = new BusinessObjectRelationship(boClass,
 224  
                                                 ddReference.getObjectAttributeName(), ddReference
 225  
                                                                 .getTargetClass());
 226  0
                                 for (PrimitiveAttributeDefinition def : ddReference
 227  
                                                 .getPrimitiveAttributes()) {
 228  0
                                         if (StringUtils.isNotBlank(attributePrefix)) {
 229  0
                                                 relationship.getParentToChildReferences().put(
 230  
                                                                 attributePrefix + "." + def.getSourceName(),
 231  
                                                                 def.getTargetName());
 232  
                                         } else {
 233  0
                                                 relationship.getParentToChildReferences().put(
 234  
                                                                 def.getSourceName(), def.getTargetName());
 235  
                                         }
 236  
                                 }
 237  0
                                 if (!keysOnly) {
 238  0
                                         for (SupportAttributeDefinition def : ddReference
 239  
                                                         .getSupportAttributes()) {
 240  0
                                                 if (StringUtils.isNotBlank(attributePrefix)) {
 241  0
                                                         relationship.getParentToChildReferences()
 242  
                                                                         .put(
 243  
                                                                                         attributePrefix + "."
 244  
                                                                                                         + def.getSourceName(),
 245  
                                                                                         def.getTargetName());
 246  0
                                                         if (def.isIdentifier()) {
 247  0
                                                                 relationship
 248  
                                                                                 .setUserVisibleIdentifierKey(attributePrefix
 249  
                                                                                                 + "." + def.getSourceName());
 250  
                                                         }
 251  
                                                 } else {
 252  0
                                                         relationship.getParentToChildReferences().put(
 253  
                                                                         def.getSourceName(), def.getTargetName());
 254  0
                                                         if (def.isIdentifier()) {
 255  0
                                                                 relationship.setUserVisibleIdentifierKey(def
 256  
                                                                                 .getSourceName());
 257  
                                                         }
 258  
                                                 }
 259  
                                         }
 260  
                                 }
 261  0
                                 return relationship;
 262  
                         }
 263  
                         // recurse down to the next object to find the relationship
 264  
 
 265  0
                         String localPrefix = StringUtils
 266  
                                         .substringBefore(attributeName, ".");
 267  0
                         String localAttributeName = StringUtils.substringAfter(
 268  
                                         attributeName, ".");
 269  0
                         if (bo == null) {
 270  0
                                 bo = (BusinessObject) ObjectUtils
 271  
                                                 .createNewObjectFromClass(boClass);
 272  
                         }
 273  0
                         Class nestedClass = ObjectUtils.getPropertyType(bo, localPrefix,
 274  
                                         getPersistenceStructureService());
 275  0
                         String fullPrefix = localPrefix;
 276  0
                         if (StringUtils.isNotBlank(attributePrefix)) {
 277  0
                                 fullPrefix = attributePrefix + "." + localPrefix;
 278  
                         }
 279  0
                         if (BusinessObject.class.isAssignableFrom(nestedClass)) {
 280  0
                                 relationship = getBusinessObjectRelationship(null, nestedClass,
 281  
                                                 localAttributeName, fullPrefix, keysOnly);
 282  
                         }
 283  0
                         return relationship;
 284  
                 }
 285  0
                 int maxSize = Integer.MAX_VALUE;
 286  
                 // try persistable reference first
 287  0
                 if (PersistableBusinessObject.class.isAssignableFrom(boClass) && persistenceStructureService.isPersistable(boClass) ) {
 288  0
                         Map<String, BusinessObjectRelationship> rels = persistenceStructureService
 289  
                                         .getRelationshipMetadata(boClass, attributeName,
 290  
                                                         attributePrefix);
 291  0
                         if (rels.size() > 0) {
 292  0
                                 for (BusinessObjectRelationship rel : rels.values()) {
 293  0
                                         if (rel.getParentToChildReferences().size() < maxSize
 294  
                                                         && isLookupable(rel.getRelatedClass())) {
 295  0
                                                 maxSize = rel.getParentToChildReferences().size();
 296  0
                                                 relationship = rel;
 297  
                                         }
 298  
                                 }
 299  
                         }
 300  0
                 } else {
 301  0
                         ModuleService moduleService = KNSServiceLocator.getKualiModuleService().getResponsibleModuleService(boClass);
 302  0
                         if(moduleService!=null && moduleService.isExternalizable(boClass)){
 303  0
                                 relationship = getRelationshipMetadata(boClass, attributeName, attributePrefix);
 304  
                                 //relationship = moduleService.getBusinessObjectRelationship(boClass, attributeName, attributePrefix);
 305  0
                                 if(relationship!=null) {
 306  0
                                         return relationship;
 307  
                                 }
 308  
                         }
 309  
                 }
 310  
 
 311  
                 // then check the DD for relationships defined there
 312  
                 // TODO move out to a separate method
 313  
                 // so that the logic for finding the relationships is similar to
 314  
                 // primitiveReference
 315  0
                 if (ddReference != null
 316  
                                 && isLookupable(ddReference.getTargetClass())
 317  
                                 && bo != null
 318  
                                 && ddReference.getPrimitiveAttributes().size() < maxSize ) {
 319  0
                         relationship = new BusinessObjectRelationship(boClass,
 320  
                                 ddReference.getObjectAttributeName(), ddReference
 321  
                                                 .getTargetClass());
 322  0
                         for (PrimitiveAttributeDefinition def : ddReference
 323  
                                         .getPrimitiveAttributes()) {
 324  0
                                 relationship.getParentToChildReferences().put(
 325  
                                                 def.getSourceName(), def.getTargetName());
 326  
                         }
 327  0
                         if (!keysOnly) {
 328  0
                                 for (SupportAttributeDefinition def : ddReference
 329  
                                                 .getSupportAttributes()) {
 330  0
                                         relationship.getParentToChildReferences().put(
 331  
                                                         def.getSourceName(), def.getTargetName());
 332  
                                 }
 333  
                         }
 334  
                 }
 335  
 
 336  0
                 return relationship;
 337  
 
 338  
         }
 339  
 
 340  
         public RelationshipDefinition getBusinessObjectRelationshipDefinition(
 341  
                         Class c, String attributeName) {
 342  0
                 return getDDRelationship(c, attributeName);
 343  
         }
 344  
 
 345  
         public RelationshipDefinition getBusinessObjectRelationshipDefinition(
 346  
                         BusinessObject bo, String attributeName) {
 347  0
                 return getBusinessObjectRelationshipDefinition(bo.getClass(),
 348  
                                 attributeName);
 349  
         }
 350  
 
 351  
         public BusinessObjectRelationship getBusinessObjectRelationship(
 352  
                         BusinessObject bo, Class boClass, String attributeName,
 353  
                         String attributePrefix, boolean keysOnly) {
 354  0
                 RelationshipDefinition ddReference = getBusinessObjectRelationshipDefinition(
 355  
                                 boClass, attributeName);
 356  0
                 return getBusinessObjectRelationship(ddReference, bo, boClass,
 357  
                                 attributeName, attributePrefix, keysOnly);
 358  
         }
 359  
 
 360  
         /**
 361  
          * Gets the dataDictionaryService attribute.
 362  
          *
 363  
          * @return Returns the dataDictionaryService.
 364  
          */
 365  
         public DataDictionaryService getDataDictionaryService() {
 366  0
                 return dataDictionaryService;
 367  
         }
 368  
 
 369  
         /**
 370  
          * Sets the dataDictionaryService attribute value.
 371  
          *
 372  
          * @param dataDictionaryService
 373  
          *            The dataDictionaryService to set.
 374  
          */
 375  
         public void setDataDictionaryService(
 376  
                         DataDictionaryService dataDictionaryService) {
 377  0
                 this.dataDictionaryService = dataDictionaryService;
 378  0
         }
 379  
 
 380  
         /**
 381  
          * Gets the businessObjectDictionaryService attribute.
 382  
          *
 383  
          * @return Returns the businessObjectDictionaryService.
 384  
          */
 385  
         public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
 386  0
                 return businessObjectDictionaryService;
 387  
         }
 388  
 
 389  
         /**
 390  
          * Sets the businessObjectDictionaryService attribute value.
 391  
          *
 392  
          * @param businessObjectDictionaryService
 393  
          *            The BusinessObjectDictionaryService to set.
 394  
          */
 395  
         public void setBusinessObjectDictionaryService(
 396  
                         BusinessObjectDictionaryService businessObjectDictionaryService) {
 397  0
                 this.businessObjectDictionaryService = businessObjectDictionaryService;
 398  0
         }
 399  
 
 400  
         /**
 401  
          * Gets the persistenceStructureService attribute.
 402  
          *
 403  
          * @return Returns the persistenceStructureService.
 404  
          */
 405  
         public PersistenceStructureService getPersistenceStructureService() {
 406  0
                 return persistenceStructureService;
 407  
         }
 408  
 
 409  
         /**
 410  
          * Sets the persistenceStructureService attribute value.
 411  
          *
 412  
          * @param persistenceStructureService
 413  
          *            The persistenceStructureService to set.
 414  
          */
 415  
         public void setPersistenceStructureService(
 416  
                         PersistenceStructureService persistenceStructureService) {
 417  0
                 this.persistenceStructureService = persistenceStructureService;
 418  0
         }
 419  
 
 420  
         /**
 421  
          *
 422  
          * This method retrieves the business object class for a specific attribute
 423  
          *
 424  
          * @param bo
 425  
          * @param attributeName
 426  
          * @return a business object class for a specific attribute
 427  
          */
 428  
         private Class getNestedBOClass(BusinessObject bo, String attributeName) {
 429  
 
 430  0
                 String[] nestedAttributes = StringUtils.split(attributeName, ".");
 431  0
                 String attributeRefName = "";
 432  0
                 Class clazz = null;
 433  0
                 if (nestedAttributes.length > 1) {
 434  0
                         String attributeStringSoFar = "";
 435  0
                         for (int i = 0; i < nestedAttributes.length - 1; i++) {
 436  
                                 try {
 437  
                                         // we need to build a string of the attribute names
 438  
                                         // depending on which iteration we're in.
 439  
                                         // so if the original attributeName string we're using is
 440  
                                         // "a.b.c.d.e", then first iteration would use
 441  
                                         // "a", 2nd "a.b", 3rd "a.b.c", etc.
 442  0
                                         if (i != 0) {
 443  0
                                                 attributeStringSoFar = attributeStringSoFar + ".";
 444  
                                         }
 445  0
                                         attributeStringSoFar = attributeStringSoFar
 446  
                                                         + nestedAttributes[i];
 447  0
                                         clazz = ObjectUtils.easyGetPropertyType(bo,
 448  
                                                         attributeStringSoFar);
 449  0
                                 } catch (InvocationTargetException ite) {
 450  0
                                         LOG.info(ite);
 451  0
                                         return null;
 452  0
                                 } catch (NoSuchMethodException nsme) {
 453  0
                                         LOG.info(nsme);
 454  0
                                         return null;
 455  0
                                 } catch (IllegalAccessException iae) {
 456  0
                                         LOG.info(iae);
 457  0
                                         return null;
 458  0
                                 }
 459  
                         }
 460  
                 }
 461  0
                 return clazz;
 462  
         }
 463  
 
 464  
         public RelationshipDefinition getDDRelationship(Class c,
 465  
                         String attributeName) {
 466  0
                 DataDictionaryEntry entryBase = dataDictionaryService
 467  
                                 .getDataDictionary().getDictionaryObjectEntry(c.getName());
 468  0
                 if (entryBase == null) {
 469  0
                         return null;
 470  
                 }
 471  
 
 472  0
                 List<RelationshipDefinition> ddRelationships = entryBase
 473  
                                 .getRelationships();
 474  0
                 RelationshipDefinition relationship = null;
 475  0
                 int minKeys = Integer.MAX_VALUE;
 476  0
                 for (RelationshipDefinition def : ddRelationships) {
 477  
                         // favor key sizes of 1 first
 478  0
                         if (def.getPrimitiveAttributes().size() == 1) {
 479  0
                                 for (PrimitiveAttributeDefinition primitive : def
 480  
                                                 .getPrimitiveAttributes()) {
 481  0
                                         if (primitive.getSourceName().equals(attributeName)
 482  
                                                         || def.getObjectAttributeName().equals(
 483  
                                                                         attributeName)) {
 484  0
                                                 relationship = def;
 485  0
                                                 minKeys = 1;
 486  0
                                                 break;
 487  
                                         }
 488  
                                 }
 489  0
                         } else if (def.getPrimitiveAttributes().size() < minKeys) {
 490  0
                                 for (PrimitiveAttributeDefinition primitive : def
 491  
                                                 .getPrimitiveAttributes()) {
 492  0
                                         if (primitive.getSourceName().equals(attributeName)
 493  
                                                         || def.getObjectAttributeName().equals(
 494  
                                                                         attributeName)) {
 495  0
                                                 relationship = def;
 496  0
                                                 minKeys = def.getPrimitiveAttributes().size();
 497  0
                                                 break;
 498  
                                         }
 499  
                                 }
 500  
                         }
 501  
                 }
 502  
                 // check the support attributes
 503  0
                 if (relationship == null) {
 504  0
                         for (RelationshipDefinition def : ddRelationships) {
 505  0
                                 if (def.hasIdentifier()) {
 506  0
                                         if (def.getIdentifier().getSourceName().equals(
 507  
                                                         attributeName)) {
 508  0
                                                 relationship = def;
 509  
                                         }
 510  
                                 }
 511  
                         }
 512  
                 }
 513  0
                 return relationship;
 514  
         }
 515  
 
 516  
         public List<BusinessObjectRelationship> getBusinessObjectRelationships( BusinessObject bo ) {
 517  0
                 if ( bo == null ) {
 518  0
                         return null;
 519  
                 }
 520  0
                 return getBusinessObjectRelationships( bo.getClass() );
 521  
         }
 522  
 
 523  
         @SuppressWarnings("unchecked")
 524  
         public List<BusinessObjectRelationship> getBusinessObjectRelationships( Class<? extends BusinessObject> boClass) {
 525  0
                 if (boClass == null) {
 526  0
                         return null;
 527  
                 }
 528  
 
 529  0
                 Map<String, Class> referenceClasses = null;
 530  0
                 if (PersistableBusinessObject.class.isAssignableFrom( boClass ) && getPersistenceStructureService().isPersistable(boClass)) {
 531  0
                         referenceClasses = getPersistenceStructureService().listReferenceObjectFields(boClass);
 532  
                 }
 533  0
                 DataDictionaryEntry ddEntry = dataDictionaryService.getDataDictionary().getDictionaryObjectEntry(boClass.getName());
 534  0
                 List<RelationshipDefinition> ddRelationships = (ddEntry == null ? new ArrayList<RelationshipDefinition>() : ddEntry.getRelationships());
 535  0
                 List<BusinessObjectRelationship> relationships = new ArrayList<BusinessObjectRelationship>();
 536  
 
 537  
                 // loop over all relationships
 538  0
                 if (referenceClasses != null) {
 539  0
                         for (Map.Entry<String, Class> entry : referenceClasses.entrySet()) {
 540  0
                                 if (isLookupable(entry.getValue())) {
 541  0
                                         Map<String, String> fkToPkRefs = persistenceStructureService.getForeignKeysForReference(boClass, entry.getKey());
 542  0
                                         BusinessObjectRelationship rel = new BusinessObjectRelationship( boClass, entry.getKey(), entry.getValue() );
 543  0
                                         for (Map.Entry<String, String> ref : fkToPkRefs.entrySet()) {
 544  0
                                                 rel.getParentToChildReferences().put(ref.getKey(), ref.getValue());
 545  
                                         }
 546  0
                                         relationships.add(rel);
 547  0
                                 }
 548  
                         }
 549  
                 }
 550  
 
 551  0
                 for (RelationshipDefinition rd : ddRelationships) {
 552  0
                         if (isLookupable(rd.getTargetClass())) {
 553  0
                                 BusinessObjectRelationship rel = new BusinessObjectRelationship( boClass, rd.getObjectAttributeName(), rd.getTargetClass());
 554  0
                                 for (PrimitiveAttributeDefinition def : rd.getPrimitiveAttributes()) {
 555  0
                                         rel.getParentToChildReferences().put(def.getSourceName(),def.getTargetName());
 556  
                                 }
 557  0
                                 relationships.add(rel);
 558  0
                         }
 559  
                 }
 560  
 
 561  0
                 return relationships;
 562  
         }
 563  
 
 564  
         /***************************************************************************
 565  
          * @see org.kuali.rice.kns.service.BusinessObjectMetaDataService#getReferencesForForeignKey(java.lang.Class,
 566  
          *      java.lang.String)
 567  
          */
 568  
         public Map<String, Class> getReferencesForForeignKey(BusinessObject bo,
 569  
                         String attributeName) {
 570  0
                 List<BusinessObjectRelationship> businessObjectRelationships = getBusinessObjectRelationships(bo);
 571  0
                 Map<String, Class> referencesForForeignKey = new HashMap<String, Class>();
 572  0
                 for (BusinessObjectRelationship businessObjectRelationship : businessObjectRelationships) {
 573  0
                         if (businessObjectRelationship != null
 574  
                                         && businessObjectRelationship.getParentToChildReferences() != null
 575  
                                         && businessObjectRelationship.getParentToChildReferences()
 576  
                                                         .containsKey(attributeName)) {
 577  0
                                 referencesForForeignKey.put(businessObjectRelationship
 578  
                                                 .getParentAttributeName(), businessObjectRelationship
 579  
                                                 .getRelatedClass());
 580  
                         }
 581  
                 }
 582  0
                 return referencesForForeignKey;
 583  
         }
 584  
 
 585  
         /***
 586  
          * @see org.kuali.core.service.BusinessObjectMetaDataService#listPrimaryKeyFieldNames(java.lang.Class)
 587  
          */
 588  
         public List listPrimaryKeyFieldNames(Class clazz) {
 589  0
                 if (persistenceStructureService.isPersistable(clazz)) {
 590  0
                         return persistenceStructureService.listPrimaryKeyFieldNames(clazz);
 591  
                 }
 592  0
                 ModuleService responsibleModuleService = getKualiModuleService()
 593  
                                 .getResponsibleModuleService(clazz);
 594  0
                 if (responsibleModuleService != null
 595  
                                 && responsibleModuleService.isExternalizable(clazz))
 596  0
                         return responsibleModuleService.listPrimaryKeyFieldNames(clazz);
 597  
 
 598  
                 // give the option to declare primary keys in the dd.
 599  
                 // this is primarly used for transient objects that lack db persistence.
 600  0
                 List<String> pks = dataDictionaryService.getDataDictionary()
 601  
                         .getBusinessObjectEntry(clazz.getName()).getPrimaryKeys();
 602  0
                 if(pks != null && !pks.isEmpty())
 603  0
                         return pks;
 604  
 
 605  0
                 return new ArrayList();
 606  
 
 607  
 
 608  
 
 609  
 
 610  
         }
 611  
 
 612  
         public KualiModuleService getKualiModuleService() {
 613  0
                 return this.kualiModuleService;
 614  
         }
 615  
 
 616  
         public void setKualiModuleService(KualiModuleService kualiModuleService) {
 617  0
                 this.kualiModuleService = kualiModuleService;
 618  0
         }
 619  
 
 620  
         public BusinessObjectRelationship getRelationshipMetadata(
 621  
                         Class businessObjectClass, String attributeName, String attributePrefix) {
 622  
 
 623  0
                 RelationshipDefinition relationshipDefinition = getDDRelationship(businessObjectClass, attributeName);
 624  0
                 if(relationshipDefinition==null) return null;
 625  0
                 BusinessObjectRelationship businessObjectRelationship =
 626  
                         new BusinessObjectRelationship(relationshipDefinition.getSourceClass(),
 627  
                                         relationshipDefinition.getObjectAttributeName(), relationshipDefinition.getTargetClass());
 628  0
                 if(!StringUtils.isEmpty(attributePrefix))
 629  0
                         attributePrefix += ".";
 630  0
                 List<PrimitiveAttributeDefinition> primitives = relationshipDefinition.getPrimitiveAttributes();
 631  0
                 for(PrimitiveAttributeDefinition primitiveAttributeDefinition: primitives){
 632  0
                         businessObjectRelationship.getParentToChildReferences().put(
 633  
                                         attributePrefix+primitiveAttributeDefinition.getSourceName(), primitiveAttributeDefinition.getTargetName());
 634  
                 }
 635  
                 /*List<SupportAttributeDefinition> supports = relationshipDefinition.getSupportAttributes();
 636  
                 for(SupportAttributeDefinition supportAttributeDefinition: supports){
 637  
                         rel.getParentToChildReferences().put(
 638  
                                         supportAttributeDefinition.getSourceName(), supportAttributeDefinition.getTargetName());
 639  
                 }*/
 640  0
                 return businessObjectRelationship;
 641  
         }
 642  
 
 643  
         public String getForeignKeyFieldName(Class businessObjectClass, String attributeName, String targetName) {
 644  
 
 645  0
                 String fkName = "";
 646  
 
 647  
                 // first try DD-based relationships
 648  0
                 RelationshipDefinition relationshipDefinition = getDDRelationship(businessObjectClass, attributeName);
 649  
 
 650  0
                 if(relationshipDefinition!=null){
 651  0
                         List<PrimitiveAttributeDefinition> primitives = relationshipDefinition.getPrimitiveAttributes();
 652  0
                         for(PrimitiveAttributeDefinition primitiveAttributeDefinition: primitives){
 653  0
                                 if(primitiveAttributeDefinition.getTargetName().equals(targetName)){
 654  0
                                         fkName = primitiveAttributeDefinition.getSourceName();
 655  0
                                         break;
 656  
                                 }
 657  
                         }
 658  
                 }
 659  
 
 660  
                 // if we can't find anything in the DD, then try the persistence service
 661  0
                 if(StringUtils.isBlank(fkName) && PersistableBusinessObject.class.isAssignableFrom(businessObjectClass) && getPersistenceStructureService().isPersistable(businessObjectClass)) {
 662  0
                         fkName =
 663  
                                 getPersistenceStructureService().getForeignKeyFieldName(businessObjectClass, attributeName, targetName);
 664  
                 }
 665  0
                 return fkName;
 666  
         }
 667  
 }