Coverage Report - org.kuali.rice.kns.web.ui.FieldBridge
 
Classes in this File Line Coverage Branch Coverage Complexity
FieldBridge
0%
0/206
0%
0/120
5.5
 
 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.web.ui;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.Collection;
 20  
 import java.util.Iterator;
 21  
 import java.util.List;
 22  
 import java.util.Set;
 23  
 
 24  
 import org.apache.commons.lang.StringUtils;
 25  
 import org.kuali.rice.core.util.ClassLoaderUtils;
 26  
 import org.kuali.rice.core.util.KeyLabelPair;
 27  
 import org.kuali.rice.kns.bo.BusinessObject;
 28  
 import org.kuali.rice.kns.datadictionary.CollectionDefinitionI;
 29  
 import org.kuali.rice.kns.datadictionary.FieldDefinition;
 30  
 import org.kuali.rice.kns.datadictionary.FieldDefinitionI;
 31  
 import org.kuali.rice.kns.datadictionary.MaintainableCollectionDefinition;
 32  
 import org.kuali.rice.kns.datadictionary.MaintainableFieldDefinition;
 33  
 import org.kuali.rice.kns.datadictionary.MaintainableItemDefinition;
 34  
 import org.kuali.rice.kns.datadictionary.MaintainableSectionDefinition;
 35  
 import org.kuali.rice.kns.datadictionary.control.ApcSelectControlDefinition;
 36  
 import org.kuali.rice.kns.datadictionary.control.ControlDefinition;
 37  
 import org.kuali.rice.kns.lookup.LookupUtils;
 38  
 import org.kuali.rice.kns.lookup.keyvalues.ApcValuesFinder;
 39  
 import org.kuali.rice.kns.lookup.keyvalues.KeyValuesFinder;
 40  
 import org.kuali.rice.kns.lookup.keyvalues.PersistableBusinessObjectValuesFinder;
 41  
 import org.kuali.rice.kns.maintenance.Maintainable;
 42  
 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
 43  
 import org.kuali.rice.kns.service.DataDictionaryService;
 44  
 import org.kuali.rice.kns.service.KNSServiceLocator;
 45  
 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
 46  
 import org.kuali.rice.kns.service.PersistenceStructureService;
 47  
 import org.kuali.rice.kns.util.FieldUtils;
 48  
 import org.kuali.rice.kns.util.KNSConstants;
 49  
 import org.kuali.rice.kns.util.MaintenanceUtils;
 50  
 import org.kuali.rice.kns.util.ObjectUtils;
 51  
 import org.kuali.rice.kns.web.format.Formatter;
 52  
 
 53  0
 public class FieldBridge {
 54  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(FieldBridge.class);
 55  
     private static DataDictionaryService dataDictionaryService;
 56  
     private static PersistenceStructureService persistenceStructureService;
 57  
     private static BusinessObjectDictionaryService businessObjectDictionaryService;
 58  
     private static MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
 59  
 
 60  
     /**
 61  
      * Sets additional properties for MaintainableField(s)
 62  
      *
 63  
      * @param field The field to populate.
 64  
      * @param definition The DD specification for the field.
 65  
      */
 66  
     public static final void setupField(Field field, FieldDefinitionI definition, Set<String> conditionallyRequiredMaintenanceFields) {
 67  0
         if (definition instanceof MaintainableFieldDefinition) {
 68  0
             MaintainableFieldDefinition maintainableFieldDefinition = ((MaintainableFieldDefinition) definition);
 69  
             
 70  0
             field.setFieldRequired(maintainableFieldDefinition.isRequired());
 71  0
             field.setReadOnly(maintainableFieldDefinition.isUnconditionallyReadOnly());
 72  0
             if (maintainableFieldDefinition.isLookupReadOnly()) {
 73  0
                     field.setFieldType(Field.LOOKUP_READONLY);
 74  
             }
 75  
 
 76  
             // set onblur and callback functions
 77  0
             if (StringUtils.isNotBlank(maintainableFieldDefinition.getWebUILeaveFieldFunction())) {
 78  0
                 field.setWebOnBlurHandler(maintainableFieldDefinition.getWebUILeaveFieldFunction());
 79  
             }
 80  
 
 81  0
             if (StringUtils.isNotBlank(maintainableFieldDefinition.getWebUILeaveFieldCallbackFunction())) {
 82  0
                 field.setWebOnBlurHandlerCallback(maintainableFieldDefinition.getWebUILeaveFieldCallbackFunction());
 83  
             }
 84  
 
 85  0
             if (maintainableFieldDefinition.getWebUILeaveFieldFunctionParameters()!=null) {
 86  0
                 field.setWebUILeaveFieldFunctionParameters(maintainableFieldDefinition.getWebUILeaveFieldFunctionParameters());
 87  
             }
 88  
             
 89  0
                         if (StringUtils.isNotBlank(maintainableFieldDefinition.getAlternateDisplayAttributeName())) {
 90  0
                                 field.setAlternateDisplayPropertyName(maintainableFieldDefinition.getAlternateDisplayAttributeName());
 91  
                         }
 92  
 
 93  0
                         if (StringUtils.isNotBlank(maintainableFieldDefinition.getAdditionalDisplayAttributeName())) {
 94  0
                                 field.setAdditionalDisplayPropertyName(maintainableFieldDefinition.getAdditionalDisplayAttributeName());
 95  
                         }
 96  
             
 97  0
             if (conditionallyRequiredMaintenanceFields != null && conditionallyRequiredMaintenanceFields.contains(field.getPropertyName())) {
 98  0
                     field.setFieldRequired(true);
 99  
             }
 100  
             
 101  0
             if (((MaintainableFieldDefinition) definition).isTriggerOnChange()) {
 102  0
                     field.setTriggerOnChange(true);
 103  
             }
 104  
         }
 105  0
     }
 106  
 
 107  
     /**
 108  
          * Uses reflection to populate the rows of the inquiry from the business
 109  
          * object value. Also formats if needed.
 110  
      *
 111  
          * @param field
 112  
          *            The Field to populate.
 113  
          * @param bo
 114  
          *            The BusinessObject from which the Field will be popualated.
 115  
      */
 116  
     public static final void populateFieldFromBusinessObject(Field field, BusinessObject bo) {
 117  0
         if (bo == null) {
 118  0
             throw new RuntimeException("Inquiry Business object is null.");
 119  
         }
 120  
 
 121  0
         field.setReadOnly(true); // inquiry fields are always read only
 122  
 
 123  0
         Formatter formatter = field.getFormatter();
 124  0
         String propertyName = field.getPropertyName();
 125  
 
 126  
         // get the field type for the property
 127  0
                 ControlDefinition fieldControl = getDataDictionaryService().getAttributeControlDefinition(bo.getClass(),
 128  
                                 propertyName);
 129  
         try {
 130  0
             Object prop = ObjectUtils.getPropertyValue(bo, field.getPropertyName());
 131  
 
 132  
                         // for select fields, display the associated label (unless we are
 133  
                         // already display an additonal attribute)
 134  0
                         String propValue = KNSConstants.EMPTY_STRING;
 135  0
                         if (fieldControl != null && fieldControl.isSelect()
 136  
                                         && StringUtils.isBlank(field.getAdditionalDisplayPropertyName())
 137  
                                         && StringUtils.isBlank(field.getAlternateDisplayPropertyName())) {
 138  0
                                 Class<KeyValuesFinder> keyValuesFinderName = ClassLoaderUtils.getClass(fieldControl
 139  
                                                 .getValuesFinderClass());
 140  0
                 KeyValuesFinder finder = keyValuesFinderName.newInstance();
 141  
 
 142  0
                 propValue = lookupFinderValue(fieldControl, prop, finder);
 143  0
             } else {
 144  0
                                 propValue = ObjectUtils.getFormattedPropertyValue(bo, field.getPropertyName(), formatter);
 145  
                     }
 146  0
                         field.setPropertyValue(propValue);
 147  
                         
 148  
                         // set additional or alternate display property values if property
 149  
                         // name is specified
 150  0
                         if (StringUtils.isNotBlank(field.getAlternateDisplayPropertyName())) {
 151  0
                                 String alternatePropertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(bo, field
 152  
                                                 .getAlternateDisplayPropertyName());
 153  0
                                 field.setAlternateDisplayPropertyValue(alternatePropertyValue);
 154  
                 }
 155  
 
 156  0
                         if (StringUtils.isNotBlank(field.getAdditionalDisplayPropertyName())) {
 157  0
                                 String additionalPropertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(bo, field
 158  
                                                 .getAdditionalDisplayPropertyName());
 159  0
                                 field.setAdditionalDisplayPropertyValue(additionalPropertyValue);
 160  
             }
 161  
 
 162  
                         // for user fields, attempt to pull the principal ID and person's
 163  
                         // name from the source object
 164  0
             if ( fieldControl != null && fieldControl.isKualiUser() ) {
 165  
                     // this is supplemental, so catch and log any errors 
 166  
                     try {
 167  0
                             if ( StringUtils.isNotBlank(field.getUniversalIdAttributeName()) ) {
 168  0
                                     Object principalId = ObjectUtils.getNestedValue(bo, field.getUniversalIdAttributeName());
 169  0
                                     if ( principalId != null ) {
 170  0
                                             field.setUniversalIdValue(principalId.toString());
 171  
                                     }
 172  
                             }
 173  0
                             if ( StringUtils.isNotBlank(field.getPersonNameAttributeName()) ) {
 174  0
                                     Object personName = ObjectUtils.getNestedValue(bo, field.getPersonNameAttributeName());
 175  0
                                     if ( personName != null ) {
 176  0
                                             field.setPersonNameValue( personName.toString() );
 177  
                                     }
 178  
                             }
 179  0
                     } catch ( Exception ex ) {
 180  0
                             LOG.warn( "Unable to get principal ID or person name property in FieldBridge.", ex );
 181  0
                     }
 182  
             }
 183  0
             FieldUtils.setInquiryURL(field, bo, propertyName);
 184  0
                 } catch (InstantiationException e) {
 185  0
             LOG.error("Unable to get instance of KeyValuesFinder: " + e.getMessage());
 186  0
             throw new RuntimeException("Unable to get instance of KeyValuesFinder: " + e.getMessage());
 187  0
                 } catch (IllegalAccessException e) {
 188  0
             LOG.error("Unable to set columns: " + e.getMessage());
 189  0
             throw new RuntimeException("Unable to set columns: " + e.getMessage());
 190  0
         }
 191  
 
 192  0
     }
 193  
 
 194  
     /**
 195  
      * This method looks up a value in a finder class.
 196  
      * @param fieldControl the type of web control that is associated with this field.
 197  
      * @param prop the property to look up - either a property name as a String, or a referenced object
 198  
      * @param finder finder to look the value up in
 199  
      * @return the value that was returned from the lookup
 200  
      */
 201  
     private static String lookupFinderValue(ControlDefinition fieldControl, Object prop, KeyValuesFinder finder) {
 202  0
         String propValue = null;
 203  
 
 204  0
         if (finder != null) {
 205  0
             if (finder instanceof ApcValuesFinder && fieldControl instanceof ApcSelectControlDefinition) {
 206  0
                 ((ApcValuesFinder) finder).setParameterNamespace(((ApcSelectControlDefinition) fieldControl).getParameterNamespace());
 207  0
                 ((ApcValuesFinder) finder).setParameterDetailType(((ApcSelectControlDefinition) fieldControl).getParameterDetailType());
 208  0
                 ((ApcValuesFinder) finder).setParameterName(((ApcSelectControlDefinition) fieldControl).getParameterName());
 209  
             }
 210  
         }
 211  
 
 212  
         // KULRICE-1808 : PersistableBusinessObjectValuesFinder is not working for inquiries that have child objects with ValuesFinder populated select lists
 213  0
         if (finder instanceof PersistableBusinessObjectValuesFinder) {
 214  0
             ((PersistableBusinessObjectValuesFinder) finder).setBusinessObjectClass(ClassLoaderUtils.getClass(fieldControl.getBusinessObjectClass()));
 215  0
             ((PersistableBusinessObjectValuesFinder) finder).setKeyAttributeName(fieldControl.getKeyAttribute());
 216  0
             ((PersistableBusinessObjectValuesFinder) finder).setLabelAttributeName(fieldControl.getLabelAttribute());
 217  0
             if (fieldControl.getIncludeBlankRow() != null) {
 218  0
                     ((PersistableBusinessObjectValuesFinder) finder).setIncludeBlankRow(fieldControl.getIncludeBlankRow());
 219  
             }
 220  0
             ((PersistableBusinessObjectValuesFinder) finder).setIncludeKeyInDescription(fieldControl.getIncludeKeyInLabel());
 221  
         }
 222  0
         List keyValues = finder.getKeyValues();
 223  0
         propValue = getPropertyValueFromList(prop, keyValues);
 224  0
         if(propValue==null)
 225  0
                 propValue = lookupInactiveFinderValue(prop, finder);
 226  0
         return propValue;
 227  
     }
 228  
     
 229  
     private static String lookupInactiveFinderValue(Object property, KeyValuesFinder finder){
 230  0
             List keyValues = finder.getKeyValues(false);
 231  0
             return getPropertyValueFromList(property, keyValues);
 232  
             
 233  
     }
 234  
     
 235  
     private static String getPropertyValueFromList(Object property, List keyValues){
 236  0
             String propertyValue = null;
 237  0
         if (property != null) {
 238  0
             for (Iterator iter = keyValues.iterator(); iter.hasNext();) {
 239  0
                 KeyLabelPair element = (KeyLabelPair) iter.next();
 240  0
                 if (element.getKey().toString().equals(property.toString())) {
 241  0
                     propertyValue = element.getLabel();
 242  0
                     break;
 243  
                 }
 244  0
             }
 245  
         }
 246  0
         return propertyValue;
 247  
     }
 248  
     
 249  
     /**
 250  
      * Determines whether field level help is enabled for the field corresponding to the businessObjectClass and attribute name
 251  
      *
 252  
      * If this value is true, then the field level help will be enabled.
 253  
      * If false, then whether a field is enabled is determined by the value returned by {@link #isMaintenanceFieldLevelHelpDisabled(Maintainable, MaintainableFieldDefinition)}
 254  
      * and the system-wide parameter setting.  Note that if a field is read-only, that may cause field-level help to not be rendered.
 255  
      *
 256  
      * @param businessObjectClass the looked up class
 257  
      * @param attributeName the attribute for the field
 258  
      * @return true if field level help is enabled, false if the value of this method should NOT be used to determine whether this method's return value
 259  
      * affects the enablement of field level help
 260  
      */
 261  
     protected static boolean isMaintenanceFieldLevelHelpEnabled(Maintainable m, MaintainableFieldDefinition fieldDefinition) {
 262  0
         if ( fieldDefinition != null ) {
 263  0
             if ( fieldDefinition.isShowFieldLevelHelp() != null && fieldDefinition.isShowFieldLevelHelp() ) {
 264  0
                 return true;
 265  
             }
 266  
         }
 267  0
         return false;
 268  
     }
 269  
 
 270  
     /**
 271  
      * Determines whether field level help is disabled for the field corresponding to the businessObjectClass and attribute name
 272  
      *
 273  
      * If this value is true and {@link #isMaintenanceFieldLevelHelpEnabled(Maintainable, MaintainableFieldDefinition)} returns false,
 274  
      * then the field level help will not be rendered.  If both this and {@link #isMaintenanceFieldLevelHelpEnabled(Maintainable, MaintainableFieldDefinition)} return false,
 275  
      * then the system-wide setting will determine whether field level help is enabled.  Note that if a field is read-only, that may cause
 276  
      * field-level help to not be rendered.
 277  
      *
 278  
      * @param businessObjectClass the looked up class
 279  
      * @param attributeName the attribute for the field
 280  
      * @return true if field level help is disabled, false if the value of this method should NOT be used to determine whether this method's return value
 281  
      * affects the enablement of field level help
 282  
      */
 283  
     protected static boolean isMaintenanceFieldLevelHelpDisabled(Maintainable m, MaintainableFieldDefinition fieldDefinition) {
 284  0
         if ( fieldDefinition != null ) {
 285  0
             if ( fieldDefinition.isShowFieldLevelHelp() != null && !fieldDefinition.isShowFieldLevelHelp() ) {
 286  0
                 return true;
 287  
             }
 288  
         }
 289  0
         return false;
 290  
     }
 291  
 
 292  
     /**
 293  
      * This method creates a Field for display on a Maintenance Document.
 294  
      *
 295  
      * @param id The DD definition for the Field (can be a Collection).
 296  
      * @param sd The DD definition for the Section in which the field will be displayed.
 297  
      * @param o The BusinessObject will be populated from this BO.
 298  
      * @param m
 299  
      * @param s The Section in which the Field will be displayed.
 300  
      * @param autoFillDefaultValues Should default values be filled in?
 301  
      * @param autoFillBlankRequiredValues Should values be filled in for fields that are required but which were left blank when submitting the form from the UI?
 302  
      * @param displayedFieldNames What fields are being displayed on the form in the UI?
 303  
      *
 304  
      * @return
 305  
      *
 306  
      * @throws InstantiationException
 307  
      * @throws IllegalAccessException
 308  
      */
 309  
     public static final Field toField(MaintainableItemDefinition id, MaintainableSectionDefinition sd, BusinessObject o, Maintainable m, Section s, List<String> displayedFieldNames, Set<String> conditionallyRequiredMaintenanceFields) throws InstantiationException, IllegalAccessException {
 310  0
         Field field = new Field();
 311  
 
 312  
         // if FieldDefiniton, simply add a Field UI object
 313  0
         if (id instanceof MaintainableFieldDefinition) {
 314  0
             MaintainableFieldDefinition maintainableFieldDefinition = (MaintainableFieldDefinition) id;
 315  0
             field = FieldUtils.getPropertyField(o.getClass(), maintainableFieldDefinition.getName(), false);
 316  
 
 317  0
                         boolean translateCodes = getMaintenanceDocumentDictionaryService().translateCodes(o.getClass());
 318  0
                         if (translateCodes) {
 319  0
                                 FieldUtils.setAdditionalDisplayPropertyForCodes(o.getClass(), field.getPropertyName(), field);
 320  
                         }
 321  
 
 322  0
             setupField(field, maintainableFieldDefinition, conditionallyRequiredMaintenanceFields);
 323  
 
 324  0
             MaintenanceUtils.setFieldQuickfinder(o, field.getPropertyName(), maintainableFieldDefinition, field, displayedFieldNames, m);
 325  0
             MaintenanceUtils.setFieldDirectInquiry(o, field.getPropertyName(), maintainableFieldDefinition, field, displayedFieldNames);
 326  
 
 327  
             // set default value
 328  
             //TODO St. Ailish says review this. A question was raised on 11-16-2006 Tuscon meeting as to why this is done here and not in the formatter.
 329  
             /*if (autoFillDefaultValues) {
 330  
                 Object defaultValue = maintainableFieldDefinition.getDefaultValue();
 331  
                 if (defaultValue != null) {
 332  
                     if (defaultValue.toString().equals("true")) {
 333  
                         defaultValue = "Yes";
 334  
                     }
 335  
                     else if (defaultValue.toString().equals("false")) {
 336  
                         defaultValue = "No";
 337  
                     }
 338  
                     field.setPropertyValue(defaultValue);
 339  
                 }
 340  
 
 341  
                 Class defaultValueFinderClass = maintainableFieldDefinition.getDefaultValueFinderClass();
 342  
                 if (defaultValueFinderClass != null) {
 343  
                     field.setPropertyValue(((ValueFinder) defaultValueFinderClass.newInstance()).getValue());
 344  
                 }
 345  
             }
 346  
 
 347  
             // if this flag is set, and the current field is required, and readonly, and blank, use the
 348  
             // defaultValueFinder if one exists
 349  
             if (autoFillBlankRequiredValues) {
 350  
                 if ( maintainableFieldDefinition.isRequired() && maintainableFieldDefinition.isUnconditionallyReadOnly() ) {
 351  
                     if ( StringUtils.isBlank( field.getPropertyValue() ) ) {
 352  
                         Class defaultValueFinderClass = maintainableFieldDefinition.getDefaultValueFinderClass();
 353  
                         if (defaultValueFinderClass != null) {
 354  
                             field.setPropertyValue(((ValueFinder) defaultValueFinderClass.newInstance()).getValue());
 355  
                         }
 356  
                     }
 357  
                 }
 358  
             }
 359  
                         */
 360  0
             field.setFieldLevelHelpEnabled(isMaintenanceFieldLevelHelpEnabled(m, maintainableFieldDefinition));
 361  0
             field.setFieldLevelHelpDisabled(isMaintenanceFieldLevelHelpDisabled(m, maintainableFieldDefinition));
 362  0
             field.setFieldLevelHelpUrl(maintainableFieldDefinition.getFieldLevelHelpUrl());
 363  
         }
 364  
 
 365  0
         return field;
 366  
 
 367  
     }
 368  
 
 369  
     /**
 370  
      * This method will return a new form for adding in a BO for a collection.
 371  
      * This should be customized in a subclass so the default behavior is to return nothing.
 372  
      *
 373  
      * @param collectionDefinition The DD definition for the Collection.
 374  
      * @param o The BusinessObject form which the new Fields will be populated.
 375  
      * @param document MaintenanceDocument instance which we ar building fields for
 376  
      * @param m
 377  
      * @param displayedFieldNames What Fields are being displayed on the form in the UI?
 378  
      * @param containerRowErrorKey The error key for the Container/Collection used for displaying error messages.
 379  
      * @param parents
 380  
      * @param hideAdd Should the add line be hidden when displaying this Collection/Container in the UI?
 381  
      * @param numberOfColumns How many columns the Fields in the Collection will be split into when displaying them in the UI.
 382  
      *
 383  
      * @return The List of new Fields.
 384  
      */
 385  
     public static final List<Field> getNewFormFields(CollectionDefinitionI collectionDefinition, BusinessObject o, Maintainable m, List<String> displayedFieldNames, Set<String> conditionallyRequiredMaintenanceFields, StringBuffer containerRowErrorKey, String parents, boolean hideAdd, int numberOfColumns) {
 386  0
         LOG.debug( "getNewFormFields" );
 387  0
         String collName = collectionDefinition.getName();
 388  
 
 389  0
         List<Field> collFields = new ArrayList<Field>();
 390  
         Collection<? extends FieldDefinitionI> collectionFields;
 391  
         //Class boClass = collectionDefinition.getBusinessObjectClass();
 392  0
         BusinessObject collBO = null;
 393  
         try {
 394  0
             collectionFields = collectionDefinition.getFields();
 395  0
             collBO = m.getNewCollectionLine(parents + collName);
 396  
 
 397  0
             if ( LOG.isDebugEnabled() ) {
 398  0
                 LOG.debug( "newBO for add line: " + collBO );
 399  
             }
 400  
 
 401  0
             for ( FieldDefinitionI fieldDefinition : collectionFields  ) {
 402  
                 // construct Field UI object from definition
 403  0
                 Field collField = FieldUtils.getPropertyField(collectionDefinition.getBusinessObjectClass(), fieldDefinition.getName(), false);
 404  
 
 405  0
                 if (fieldDefinition instanceof MaintainableFieldDefinition) {
 406  0
                     setupField(collField, (MaintainableFieldDefinition)fieldDefinition, conditionallyRequiredMaintenanceFields);
 407  
                 }
 408  
                 //generate the error key for the add row
 409  0
                 String[] nameParts = StringUtils.split(collField.getPropertyName(), ".");
 410  0
                 String fieldErrorKey = KNSConstants.MAINTENANCE_NEW_MAINTAINABLE + KNSConstants.ADD_PREFIX + ".";
 411  0
                 fieldErrorKey += collName + ".";
 412  0
                 for (int i = 0; i < nameParts.length; i++) {
 413  0
                     fieldErrorKey += nameParts[i];
 414  0
                     containerRowErrorKey.append(fieldErrorKey);
 415  0
                     if (i < nameParts.length) {
 416  0
                         fieldErrorKey += ".";
 417  0
                         containerRowErrorKey.append(",");
 418  
                     }
 419  
                 }
 420  
 
 421  
                 //  set the QuickFinderClass
 422  0
                 BusinessObject collectionBoInstance = (BusinessObject) collectionDefinition.getBusinessObjectClass().newInstance();
 423  0
                 FieldUtils.setInquiryURL(collField, collectionBoInstance, fieldDefinition.getName());
 424  0
                 if (collectionDefinition instanceof MaintainableCollectionDefinition) {
 425  0
                     MaintenanceUtils.setFieldQuickfinder(collectionBoInstance, parents+collectionDefinition.getName(), true, 0, fieldDefinition.getName(), collField, displayedFieldNames, m, (MaintainableFieldDefinition) fieldDefinition);
 426  0
                     MaintenanceUtils.setFieldDirectInquiry(collectionBoInstance, parents+collectionDefinition.getName(), true, 0, fieldDefinition.getName(), collField, displayedFieldNames, m, (MaintainableFieldDefinition) fieldDefinition);
 427  
                 }
 428  
                 else {
 429  0
                     LookupUtils.setFieldQuickfinder(collectionBoInstance, parents+collectionDefinition.getName(), true, 0, fieldDefinition.getName(), collField, displayedFieldNames, m);
 430  0
                     LookupUtils.setFieldDirectInquiry(collectionBoInstance, fieldDefinition.getName(), collField);
 431  
                 }
 432  
 
 433  0
                 collFields.add(collField);
 434  0
             }
 435  
 
 436  0
         } catch (InstantiationException e) {
 437  0
             LOG.error("Unable to create instance of object class" + e.getMessage());
 438  0
             throw new RuntimeException("Unable to create instance of object class" + e.getMessage());
 439  0
         } catch (IllegalAccessException e) {
 440  0
             LOG.error("Unable to create instance of object class" + e.getMessage());
 441  0
             throw new RuntimeException("Unable to create instance of object class" + e.getMessage());
 442  0
         }
 443  
 
 444  
         // populate field values from business object
 445  0
         collFields = FieldUtils.populateFieldsFromBusinessObject(collFields,collBO);
 446  
 
 447  
         // need to append the prefix afterwards since the population command (above)
 448  
         // does not handle the prefixes on the property names
 449  0
         for ( Field field : collFields ) {
 450  
             // prefix name for add line
 451  0
             field.setPropertyName(KNSConstants.MAINTENANCE_ADD_PREFIX + parents + collectionDefinition.getName() + "." + field.getPropertyName());
 452  
         }
 453  0
         LOG.debug("Error Key for section " + collectionDefinition.getName() + " : " + containerRowErrorKey.toString());
 454  
 
 455  
         
 456  0
         collFields = constructContainerField(collectionDefinition, parents, o, hideAdd, numberOfColumns, collName, collFields);
 457  
 
 458  0
         return collFields;
 459  
     }
 460  
 
 461  
     /**
 462  
      * 
 463  
      * This method handles setting up a container field not including the add fields
 464  
      * 
 465  
      * @param collectionDefinition
 466  
      * @param parents
 467  
      * @param o
 468  
      * @param hideAdd
 469  
      * @param numberOfColumns
 470  
      * @param collName
 471  
      * @param collFields
 472  
      * @return
 473  
      */
 474  
     public static List<Field> constructContainerField(CollectionDefinitionI collectionDefinition, String parents, BusinessObject o, boolean hideAdd, int numberOfColumns, String collName, List<Field> collFields) {
 475  
         // get label for collection
 476  0
         String collectionLabel = getDataDictionaryService().getCollectionLabel(o.getClass(), collectionDefinition.getName());
 477  
 
 478  
         // retrieve the summary label either from the override or from the DD
 479  0
         String collectionElementLabel = collectionDefinition.getSummaryTitle();
 480  0
         if(StringUtils.isEmpty(collectionElementLabel)){
 481  0
             collectionElementLabel = getDataDictionaryService().getCollectionElementLabel(o.getClass().getName(), collectionDefinition.getName(),collectionDefinition.getBusinessObjectClass());
 482  
         }
 483  
 
 484  
         // container field
 485  
         Field containerField;
 486  0
         containerField = FieldUtils.constructContainerField(collName, collectionLabel, collFields, numberOfColumns);
 487  0
         if(StringUtils.isNotEmpty(collectionElementLabel)) {
 488  0
             containerField.setContainerElementName(collectionElementLabel);
 489  
         }
 490  0
         collFields = new ArrayList();
 491  0
         collFields.add(containerField);
 492  
 
 493  
         // field button for adding lines
 494  0
         if(!hideAdd  && collectionDefinition.getIncludeAddLine()) {
 495  0
             Field field = new Field();
 496  
 
 497  0
             String addButtonName = KNSConstants.DISPATCH_REQUEST_PARAMETER + "." + KNSConstants.ADD_LINE_METHOD + "." + parents + collectionDefinition.getName() + "." + KNSConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL + collectionDefinition.getBusinessObjectClass().getName() + KNSConstants.METHOD_TO_CALL_BOPARM_RIGHT_DEL;
 498  0
             field.setPropertyName(addButtonName);
 499  0
             field.setFieldType(Field.IMAGE_SUBMIT);
 500  0
             field.setPropertyValue("images/tinybutton-add1.gif");
 501  
             // collFields.add(field);
 502  0
             containerField.getContainerRows().add(new Row(field));
 503  
         }
 504  
 
 505  0
         if (collectionDefinition instanceof MaintainableCollectionDefinition) {
 506  0
             if (FieldUtils.isCollectionMultipleLookupEnabled((MaintainableCollectionDefinition) collectionDefinition)) {
 507  0
                 FieldUtils.modifyFieldToSupportMultipleValueLookups(containerField, parents, (MaintainableCollectionDefinition) collectionDefinition);
 508  
             }
 509  
         }
 510  
 
 511  0
         return collFields;
 512  
     }
 513  
 
 514  
     /**
 515  
      * Call getNewFormFields with no parents.
 516  
      *
 517  
      * @see #getNewFormFields(CollectionDefinitionI, BusinessObject, Maintainable, List, StringBuffer, String, boolean, int)
 518  
      */
 519  
     public static final List<Field> getNewFormFields(MaintainableCollectionDefinition collectionDefinition, BusinessObject o, Maintainable m, List<String> displayedFieldNames, Set<String> conditionallyRequiredMaintenanceFields, StringBuffer containerRowErrorKey, int numberOfColumns) {
 520  0
         String parent = "";
 521  0
         return getNewFormFields(collectionDefinition, o, m, displayedFieldNames, conditionallyRequiredMaintenanceFields, containerRowErrorKey, parent, false, numberOfColumns);
 522  
     }
 523  
 
 524  
     /**
 525  
      * Create a Field for display on an Inquiry screen.
 526  
      *
 527  
      * @param d The DD definition for the Field.
 528  
      * @param o The BusinessObject from which the Field will be populated.
 529  
      * @param s The Section in which the Field will be displayed.
 530  
      *
 531  
      * @return The populated Field.
 532  
      */
 533  
     public static Field toField(FieldDefinition d, BusinessObject o, Section s) {
 534  0
         Field field = FieldUtils.getPropertyField(o.getClass(), d.getAttributeName(), false);
 535  
         
 536  0
         FieldUtils.setInquiryURL(field, o, field.getPropertyName());
 537  
 
 538  0
                 String alternateDisplayPropertyName = getBusinessObjectDictionaryService()
 539  
                                 .getInquiryFieldAlternateDisplayAttributeName(o.getClass(), d.getAttributeName());
 540  0
                 if (StringUtils.isNotBlank(alternateDisplayPropertyName)) {
 541  0
                         field.setAlternateDisplayPropertyName(alternateDisplayPropertyName);
 542  
                 }
 543  
 
 544  0
                 String additionalDisplayPropertyName = getBusinessObjectDictionaryService()
 545  
                                 .getInquiryFieldAdditionalDisplayAttributeName(o.getClass(), d.getAttributeName());
 546  0
                 if (StringUtils.isNotBlank(additionalDisplayPropertyName)) {
 547  0
                         field.setAdditionalDisplayPropertyName(additionalDisplayPropertyName);
 548  
                 }
 549  
                 else {
 550  0
                         boolean translateCodes = getBusinessObjectDictionaryService().tranlateCodesInInquiry(o.getClass());
 551  0
                         if (translateCodes) {
 552  0
                                 FieldUtils.setAdditionalDisplayPropertyForCodes(o.getClass(), d.getAttributeName(), field);
 553  
                         }
 554  
                 }
 555  
 
 556  0
         populateFieldFromBusinessObject(field, o);
 557  
 
 558  0
         return field;
 559  
     }
 560  
 
 561  
         public static DataDictionaryService getDataDictionaryService() {
 562  0
             if (dataDictionaryService == null) {
 563  0
                     dataDictionaryService = KNSServiceLocator.getDataDictionaryService();
 564  
             }
 565  0
                 return dataDictionaryService;
 566  
         }
 567  
 
 568  
         public static PersistenceStructureService getPersistenceStructureService() {
 569  0
             if (persistenceStructureService == null) {
 570  0
                     persistenceStructureService = KNSServiceLocator.getPersistenceStructureService();
 571  
             }
 572  0
                 return persistenceStructureService;
 573  
         }
 574  
 
 575  
         public static BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
 576  0
             if (businessObjectDictionaryService == null) {
 577  0
                     businessObjectDictionaryService = KNSServiceLocator.getBusinessObjectDictionaryService();
 578  
             }
 579  0
                 return businessObjectDictionaryService; 
 580  
         }
 581  
         
 582  
         public static MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
 583  0
             if (maintenanceDocumentDictionaryService == null) {
 584  0
                     maintenanceDocumentDictionaryService = KNSServiceLocator.getMaintenanceDocumentDictionaryService();
 585  
             }
 586  0
                 return maintenanceDocumentDictionaryService; 
 587  
         }
 588  
 
 589  
 }
 590