Coverage Report - org.kuali.rice.kns.service.impl.BusinessObjectMetaDataServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
BusinessObjectMetaDataServiceImpl
0%
0/181
0%
0/150
4.913
 
 1  
 /**
 2  
  * Copyright 2005-2011 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.datadictionary.FieldDefinition;
 28  
 import org.kuali.rice.kns.datadictionary.InquirySectionDefinition;
 29  
 import org.kuali.rice.kns.service.BusinessObjectMetaDataService;
 30  
 import org.kuali.rice.krad.bo.BusinessObject;
 31  
 import org.kuali.rice.krad.bo.DataObjectRelationship;
 32  
 import org.kuali.rice.krad.bo.PersistableBusinessObject;
 33  
 import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
 34  
 import org.kuali.rice.krad.datadictionary.PrimitiveAttributeDefinition;
 35  
 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
 36  
 import org.kuali.rice.krad.datadictionary.SupportAttributeDefinition;
 37  
 import org.kuali.rice.krad.valuefinder.ValueFinder;
 38  
 import org.kuali.rice.krad.service.BusinessObjectDictionaryService;
 39  
 import org.kuali.rice.krad.service.DataDictionaryService;
 40  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 41  
 import org.kuali.rice.krad.service.ModuleService;
 42  
 import org.kuali.rice.krad.service.PersistenceStructureService;
 43  
 import org.kuali.rice.krad.service.impl.DataObjectMetaDataServiceImpl;
 44  
 import org.kuali.rice.krad.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  
 @Deprecated
 56  0
 public class BusinessObjectMetaDataServiceImpl extends DataObjectMetaDataServiceImpl implements BusinessObjectMetaDataService {
 57  0
         private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
 58  
                         .getLogger(BusinessObjectMetaDataServiceImpl.class);
 59  
 
 60  
         private BusinessObjectDictionaryService businessObjectDictionaryService;
 61  
 
 62  
         public Collection<String> getCollectionNames(BusinessObject bo) {
 63  0
                 return getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(bo.getClass().getName())
 64  
                                 .getCollectionNames();
 65  
         }
 66  
 
 67  
         public Collection<String> getInquirableFieldNames(Class boClass, String sectionTitle) {
 68  0
                 return businessObjectDictionaryService.getInquiryFieldNames(boClass, sectionTitle);
 69  
         }
 70  
 
 71  
         public List<String> getLookupableFieldNames(Class boClass) {
 72  0
                 return businessObjectDictionaryService.getLookupFieldNames(boClass);
 73  
         }
 74  
 
 75  
         public String getLookupFieldDefaultValue(Class businessObjectClass, String attributeName) {
 76  0
                 return businessObjectDictionaryService.getLookupFieldDefaultValue(businessObjectClass, attributeName);
 77  
         }
 78  
 
 79  
         public Class getLookupFieldDefaultValueFinderClass(Class businessObjectClass, String attributeName) {
 80  0
                 return businessObjectDictionaryService
 81  
                                 .getLookupFieldDefaultValueFinderClass(businessObjectClass, attributeName);
 82  
         }
 83  
 
 84  
         /** {@inheritDoc} */
 85  
         public String getLookupFieldQuickfinderParameterString(Class businessObjectClass, String attributeName) {
 86  0
                 return businessObjectDictionaryService.getLookupFieldQuickfinderParameterString(businessObjectClass,
 87  
                                 attributeName);
 88  
         }
 89  
 
 90  
         /** {@inheritDoc} */
 91  
         public Class<? extends ValueFinder> getLookupFieldQuickfinderParameterStringBuilderClass(Class businessObjectClass,
 92  
                         String attributeName) {
 93  0
                 return businessObjectDictionaryService.getLookupFieldQuickfinderParameterStringBuilderClass(
 94  
                                 businessObjectClass, attributeName);
 95  
         }
 96  
 
 97  
         public boolean isAttributeInquirable(Class boClass, String attributeName, String sectionTitle) {
 98  0
                 Collection sections = businessObjectDictionaryService.getInquirySections(boClass);
 99  0
                 boolean isInquirable = true;
 100  
 
 101  0
                 Iterator iter = sections.iterator();
 102  
 
 103  0
                 while (iter.hasNext()) {
 104  0
                         InquirySectionDefinition def = (InquirySectionDefinition) iter.next();
 105  0
                         for (FieldDefinition field : def.getInquiryFields()) {
 106  0
                                 if (field.getAttributeName().equalsIgnoreCase(attributeName)) {
 107  0
                                         isInquirable = !field.isNoInquiry();
 108  
                                 }
 109  
                         }
 110  0
                 }
 111  0
                 if (isInquirable) {
 112  0
                         Object obj = null;
 113  0
                         if (boClass != null && BusinessObject.class.isAssignableFrom(boClass)) {
 114  0
                                 obj = ObjectUtils.createNewObjectFromClass(boClass);
 115  
                         }
 116  
 
 117  0
                         if (obj != null) {
 118  0
                                 BusinessObject bo = (BusinessObject) obj;
 119  0
                                 Class clazz = getNestedBOClass(bo, attributeName);
 120  0
                                 if (clazz != null && BusinessObject.class.isAssignableFrom(clazz)) {
 121  0
                                         return businessObjectDictionaryService.isInquirable(clazz);
 122  
                                 }
 123  
                                 else {
 124  0
                                         return false;
 125  
                                 }
 126  
                         }
 127  
                         else {
 128  0
                                 return false;
 129  
                         }
 130  
 
 131  
                 }
 132  
 
 133  0
                 return isInquirable;
 134  
         }
 135  
 
 136  
         public boolean isInquirable(Class boClass) {
 137  0
                 boolean inquirable = false;
 138  0
                 ModuleService moduleService = getKualiModuleService().getResponsibleModuleService(boClass);
 139  0
                 if (moduleService != null && moduleService.isExternalizable(boClass)) {
 140  0
                         inquirable = moduleService.isExternalizableBusinessObjectInquirable(boClass);
 141  
                 }
 142  
                 else {
 143  0
                         Boolean isLookupable = businessObjectDictionaryService.isInquirable(boClass);
 144  0
                         if (isLookupable != null) {
 145  0
                                 inquirable = isLookupable.booleanValue();
 146  
                         }
 147  
                 }
 148  0
                 return inquirable;
 149  
         }
 150  
 
 151  
         public boolean isAttributeLookupable(Class boClass, String attributeName) {
 152  0
                 Object obj = null;
 153  0
                 if (boClass != null && BusinessObject.class.isAssignableFrom(boClass)) {
 154  0
                         obj = ObjectUtils.createNewObjectFromClass(boClass);
 155  
                 }
 156  0
                 if (obj != null) {
 157  0
                         BusinessObject bo = (BusinessObject) obj;
 158  0
                         DataObjectRelationship relationship = getBusinessObjectRelationship(bo, attributeName);
 159  
 
 160  0
                         if (relationship != null && relationship.getRelatedClass() != null
 161  
                                         && BusinessObject.class.isAssignableFrom(relationship.getRelatedClass())) {
 162  0
                                 return isLookupable(relationship.getRelatedClass());
 163  
                         }
 164  
                         else {
 165  0
                                 return false;
 166  
                         }
 167  
                 }
 168  
                 else {
 169  0
                         return false;
 170  
                 }
 171  
         }
 172  
 
 173  
         public boolean isLookupable(Class boClass) {
 174  0
                 boolean lookupable = false;
 175  0
                 ModuleService moduleService =  getKualiModuleService().getResponsibleModuleService(boClass);
 176  0
                 if (moduleService != null && moduleService.isExternalizable(boClass)) {
 177  0
                         lookupable = moduleService.isExternalizableBusinessObjectLookupable(boClass);
 178  
                 }
 179  
                 else {
 180  0
                         Boolean isLookupable = businessObjectDictionaryService.isLookupable(boClass);
 181  0
                         if (isLookupable != null) {
 182  0
                                 lookupable = isLookupable.booleanValue();
 183  
                         }
 184  
                 }
 185  0
                 return lookupable;
 186  
         }
 187  
 
 188  
         public DataObjectRelationship getBusinessObjectRelationship(BusinessObject bo, String attributeName) {
 189  0
                 return getBusinessObjectRelationship(bo, bo.getClass(), attributeName, "", true);
 190  
         }
 191  
 
 192  
         // TODO: four different exit points?!
 193  
         public DataObjectRelationship getBusinessObjectRelationship(RelationshipDefinition ddReference,
 194  
                         BusinessObject bo, Class boClass, String attributeName, String attributePrefix, boolean keysOnly) {
 195  
 
 196  0
                 DataObjectRelationship relationship = null;
 197  
 
 198  
                 // if it is nested then replace the bo and attributeName with the
 199  
                 // sub-refs
 200  0
                 if (ObjectUtils.isNestedAttribute(attributeName)) {
 201  0
                         if (ddReference != null) {
 202  0
                                 relationship = new DataObjectRelationship(boClass, ddReference.getObjectAttributeName(),
 203  
                                                 ddReference.getTargetClass());
 204  0
                                 for (PrimitiveAttributeDefinition def : ddReference.getPrimitiveAttributes()) {
 205  0
                                         if (StringUtils.isNotBlank(attributePrefix)) {
 206  0
                                                 relationship.getParentToChildReferences().put(attributePrefix + "." + def.getSourceName(),
 207  
                                                                 def.getTargetName());
 208  
                                         }
 209  
                                         else {
 210  0
                                                 relationship.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
 211  
                                         }
 212  
                                 }
 213  0
                                 if (!keysOnly) {
 214  0
                                         for (SupportAttributeDefinition def : ddReference.getSupportAttributes()) {
 215  0
                                                 if (StringUtils.isNotBlank(attributePrefix)) {
 216  0
                                                         relationship.getParentToChildReferences().put(attributePrefix + "." + def.getSourceName(),
 217  
                                                                         def.getTargetName());
 218  0
                                                         if (def.isIdentifier()) {
 219  0
                                                                 relationship.setUserVisibleIdentifierKey(attributePrefix + "." + def.getSourceName());
 220  
                                                         }
 221  
                                                 }
 222  
                                                 else {
 223  0
                                                         relationship.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
 224  0
                                                         if (def.isIdentifier()) {
 225  0
                                                                 relationship.setUserVisibleIdentifierKey(def.getSourceName());
 226  
                                                         }
 227  
                                                 }
 228  
                                         }
 229  
                                 }
 230  0
                                 return relationship;
 231  
                         }
 232  
                         // recurse down to the next object to find the relationship
 233  
 
 234  0
                         String localPrefix = StringUtils.substringBefore(attributeName, ".");
 235  0
                         String localAttributeName = StringUtils.substringAfter(attributeName, ".");
 236  0
                         if (bo == null) {
 237  0
                                 bo = (BusinessObject) ObjectUtils.createNewObjectFromClass(boClass);
 238  
                         }
 239  0
                         Class nestedClass = ObjectUtils.getPropertyType(bo, localPrefix, getPersistenceStructureService());
 240  0
                         String fullPrefix = localPrefix;
 241  0
                         if (StringUtils.isNotBlank(attributePrefix)) {
 242  0
                                 fullPrefix = attributePrefix + "." + localPrefix;
 243  
                         }
 244  0
                         if (BusinessObject.class.isAssignableFrom(nestedClass)) {
 245  0
                                 relationship = getBusinessObjectRelationship(null, nestedClass, localAttributeName, fullPrefix,
 246  
                                                 keysOnly);
 247  
                         }
 248  0
                         return relationship;
 249  
                 }
 250  0
                 int maxSize = Integer.MAX_VALUE;
 251  
                 // try persistable reference first
 252  0
                 if (PersistableBusinessObject.class.isAssignableFrom(boClass)
 253  
                                 && getPersistenceStructureService().isPersistable(boClass)) {
 254  0
                         Map<String, DataObjectRelationship> rels = getPersistenceStructureService().getRelationshipMetadata(boClass,
 255  
                                         attributeName, attributePrefix);
 256  0
                         if (rels.size() > 0) {
 257  0
                                 for (DataObjectRelationship rel : rels.values()) {
 258  0
                                         if (rel.getParentToChildReferences().size() < maxSize && isLookupable(rel.getRelatedClass())) {
 259  0
                                                 maxSize = rel.getParentToChildReferences().size();
 260  0
                                                 relationship = rel;
 261  
                                         }
 262  
                                 }
 263  
                         }
 264  0
                 }
 265  
                 else {
 266  0
                         ModuleService moduleService = KRADServiceLocatorWeb.getKualiModuleService()
 267  
                                         .getResponsibleModuleService(boClass);
 268  0
                         if (moduleService != null && moduleService.isExternalizable(boClass)) {
 269  0
                                 relationship = getRelationshipMetadata(boClass, attributeName, attributePrefix);
 270  
                                 // relationship =
 271  
                                 // moduleService.getBusinessObjectRelationship(boClass,
 272  
                                 // attributeName, attributePrefix);
 273  0
                                 if (relationship != null) {
 274  0
                                         return relationship;
 275  
                                 }
 276  
                         }
 277  
                 }
 278  
 
 279  
                 // then check the DD for relationships defined there
 280  
                 // TODO move out to a separate method
 281  
                 // so that the logic for finding the relationships is similar to
 282  
                 // primitiveReference
 283  0
                 if (ddReference != null && isLookupable(ddReference.getTargetClass()) && bo != null
 284  
                                 && ddReference.getPrimitiveAttributes().size() < maxSize) {
 285  0
                         relationship = new DataObjectRelationship(boClass, ddReference.getObjectAttributeName(),
 286  
                                         ddReference.getTargetClass());
 287  0
                         for (PrimitiveAttributeDefinition def : ddReference.getPrimitiveAttributes()) {
 288  0
                                 relationship.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
 289  
                         }
 290  0
                         if (!keysOnly) {
 291  0
                                 for (SupportAttributeDefinition def : ddReference.getSupportAttributes()) {
 292  0
                                         relationship.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
 293  
                                 }
 294  
                         }
 295  
                 }
 296  
 
 297  0
                 return relationship;
 298  
 
 299  
         }
 300  
 
 301  
 
 302  
 
 303  
         public RelationshipDefinition getBusinessObjectRelationshipDefinition(Class c, String attributeName) {
 304  0
                 return getDictionaryRelationship(c, attributeName);
 305  
         }
 306  
 
 307  
         public RelationshipDefinition getBusinessObjectRelationshipDefinition(BusinessObject bo, String attributeName) {
 308  0
                 return getBusinessObjectRelationshipDefinition(bo.getClass(), attributeName);
 309  
         }
 310  
 
 311  
         public DataObjectRelationship getBusinessObjectRelationship(BusinessObject bo, Class boClass,
 312  
                         String attributeName, String attributePrefix, boolean keysOnly) {
 313  0
                 RelationshipDefinition ddReference = getBusinessObjectRelationshipDefinition(boClass, attributeName);
 314  0
                 return getBusinessObjectRelationship(ddReference, bo, boClass, attributeName, attributePrefix, keysOnly);
 315  
         }
 316  
 
 317  
         /**
 318  
          * Gets the businessObjectDictionaryService attribute.
 319  
          * 
 320  
          * @return Returns the businessObjectDictionaryService.
 321  
          */
 322  
         public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
 323  0
                 return businessObjectDictionaryService;
 324  
         }
 325  
 
 326  
         /**
 327  
          * Sets the businessObjectDictionaryService attribute value.
 328  
          * 
 329  
          * @param businessObjectDictionaryService
 330  
          *            The BusinessObjectDictionaryService to set.
 331  
          */
 332  
         public void setBusinessObjectDictionaryService(BusinessObjectDictionaryService businessObjectDictionaryService) {
 333  0
                 this.businessObjectDictionaryService = businessObjectDictionaryService;
 334  0
         }
 335  
 
 336  
         /**
 337  
          * 
 338  
          * This method retrieves the business object class for a specific attribute
 339  
          * 
 340  
          * @param bo
 341  
          * @param attributeName
 342  
          * @return a business object class for a specific attribute
 343  
          */
 344  
         private Class getNestedBOClass(BusinessObject bo, String attributeName) {
 345  
 
 346  0
                 String[] nestedAttributes = StringUtils.split(attributeName, ".");
 347  0
                 String attributeRefName = "";
 348  0
                 Class clazz = null;
 349  0
                 if (nestedAttributes.length > 1) {
 350  0
                         String attributeStringSoFar = "";
 351  0
                         for (int i = 0; i < nestedAttributes.length - 1; i++) {
 352  
                                 try {
 353  
                                         // we need to build a string of the attribute names
 354  
                                         // depending on which iteration we're in.
 355  
                                         // so if the original attributeName string we're using is
 356  
                                         // "a.b.c.d.e", then first iteration would use
 357  
                                         // "a", 2nd "a.b", 3rd "a.b.c", etc.
 358  0
                                         if (i != 0) {
 359  0
                                                 attributeStringSoFar = attributeStringSoFar + ".";
 360  
                                         }
 361  0
                                         attributeStringSoFar = attributeStringSoFar + nestedAttributes[i];
 362  0
                                         clazz = ObjectUtils.easyGetPropertyType(bo, attributeStringSoFar);
 363  
                                 }
 364  0
                                 catch (InvocationTargetException ite) {
 365  0
                                         LOG.info(ite);
 366  0
                                         return null;
 367  
                                 }
 368  0
                                 catch (NoSuchMethodException nsme) {
 369  0
                                         LOG.info(nsme);
 370  0
                                         return null;
 371  
                                 }
 372  0
                                 catch (IllegalAccessException iae) {
 373  0
                                         LOG.info(iae);
 374  0
                                         return null;
 375  0
                                 }
 376  
                         }
 377  
                 }
 378  0
                 return clazz;
 379  
         }
 380  
 
 381  
         public List<DataObjectRelationship> getBusinessObjectRelationships(BusinessObject bo) {
 382  0
                 if (bo == null) {
 383  0
                         return null;
 384  
                 }
 385  0
                 return getBusinessObjectRelationships(bo.getClass());
 386  
         }
 387  
 
 388  
         @SuppressWarnings("unchecked")
 389  
         public List<DataObjectRelationship> getBusinessObjectRelationships(Class<? extends BusinessObject> boClass) {
 390  0
                 if (boClass == null) {
 391  0
                         return null;
 392  
                 }
 393  
 
 394  0
                 Map<String, Class> referenceClasses = null;
 395  0
                 if (PersistableBusinessObject.class.isAssignableFrom(boClass)
 396  
                                 && getPersistenceStructureService().isPersistable(boClass)) {
 397  0
                         referenceClasses = getPersistenceStructureService().listReferenceObjectFields(boClass);
 398  
                 }
 399  0
                 DataDictionaryEntry ddEntry = getDataDictionaryService().getDataDictionary().getDictionaryObjectEntry(
 400  
                                 boClass.getName());
 401  0
                 List<RelationshipDefinition> ddRelationships = (ddEntry == null ? new ArrayList<RelationshipDefinition>()
 402  
                                 : ddEntry.getRelationships());
 403  0
                 List<DataObjectRelationship> relationships = new ArrayList<DataObjectRelationship>();
 404  
 
 405  
                 // loop over all relationships
 406  0
                 if (referenceClasses != null) {
 407  0
                         for (Map.Entry<String, Class> entry : referenceClasses.entrySet()) {
 408  0
                                 if (isLookupable(entry.getValue())) {
 409  0
                                         Map<String, String> fkToPkRefs = getPersistenceStructureService().getForeignKeysForReference(boClass,
 410  
                                                         entry.getKey());
 411  0
                                         DataObjectRelationship rel = new DataObjectRelationship(boClass, entry.getKey(),
 412  
                                                         entry.getValue());
 413  0
                                         for (Map.Entry<String, String> ref : fkToPkRefs.entrySet()) {
 414  0
                                                 rel.getParentToChildReferences().put(ref.getKey(), ref.getValue());
 415  
                                         }
 416  0
                                         relationships.add(rel);
 417  0
                                 }
 418  
                         }
 419  
                 }
 420  
 
 421  0
                 for (RelationshipDefinition rd : ddRelationships) {
 422  0
                         if (isLookupable(rd.getTargetClass())) {
 423  0
                                 DataObjectRelationship rel = new DataObjectRelationship(boClass, rd.getObjectAttributeName(),
 424  
                                                 rd.getTargetClass());
 425  0
                                 for (PrimitiveAttributeDefinition def : rd.getPrimitiveAttributes()) {
 426  0
                                         rel.getParentToChildReferences().put(def.getSourceName(), def.getTargetName());
 427  
                                 }
 428  0
                                 relationships.add(rel);
 429  0
                         }
 430  
                 }
 431  
 
 432  0
                 return relationships;
 433  
         }
 434  
 
 435  
         /***************************************************************************
 436  
          * @see org.kuali.rice.kns.service.BusinessObjectMetaDataService#getReferencesForForeignKey(java.lang.Class,
 437  
          *      java.lang.String)
 438  
          */
 439  
         public Map<String, Class> getReferencesForForeignKey(BusinessObject bo, String attributeName) {
 440  0
                 List<DataObjectRelationship> dataObjectRelationships = getBusinessObjectRelationships(bo);
 441  0
                 Map<String, Class> referencesForForeignKey = new HashMap<String, Class>();
 442  0
                 for (DataObjectRelationship dataObjectRelationship : dataObjectRelationships) {
 443  0
                         if (dataObjectRelationship != null && dataObjectRelationship.getParentToChildReferences() != null
 444  
                                         && dataObjectRelationship.getParentToChildReferences().containsKey(attributeName)) {
 445  0
                                 referencesForForeignKey.put(dataObjectRelationship.getParentAttributeName(),
 446  
                                                 dataObjectRelationship.getRelatedClass());
 447  
                         }
 448  
                 }
 449  0
                 return referencesForForeignKey;
 450  
         }
 451  
 
 452  
         public String getForeignKeyFieldName(Class businessObjectClass, String attributeName, String targetName) {
 453  
 
 454  0
                 String fkName = "";
 455  
 
 456  
                 // first try DD-based relationships
 457  0
                 RelationshipDefinition relationshipDefinition = getDictionaryRelationship(businessObjectClass, attributeName);
 458  
 
 459  0
                 if (relationshipDefinition != null) {
 460  0
                         List<PrimitiveAttributeDefinition> primitives = relationshipDefinition.getPrimitiveAttributes();
 461  0
                         for (PrimitiveAttributeDefinition primitiveAttributeDefinition : primitives) {
 462  0
                                 if (primitiveAttributeDefinition.getTargetName().equals(targetName)) {
 463  0
                                         fkName = primitiveAttributeDefinition.getSourceName();
 464  0
                                         break;
 465  
                                 }
 466  
                         }
 467  
                 }
 468  
 
 469  
                 // if we can't find anything in the DD, then try the persistence service
 470  0
                 if (StringUtils.isBlank(fkName) && PersistableBusinessObject.class.isAssignableFrom(businessObjectClass)
 471  
                                 && getPersistenceStructureService().isPersistable(businessObjectClass)) {
 472  0
                         fkName = getPersistenceStructureService().getForeignKeyFieldName(businessObjectClass, attributeName,
 473  
                                         targetName);
 474  
                 }
 475  0
                 return fkName;
 476  
         }
 477  
 }