Coverage Report - org.kuali.rice.krad.web.ui.SectionBridge
 
Classes in this File Line Coverage Branch Coverage Complexity
SectionBridge
0%
0/366
0%
0/256
6.773
 
 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.krad.web.ui;
 17  
 
 18  
 import org.apache.commons.beanutils.PropertyUtils;
 19  
 import org.apache.commons.lang.StringUtils;
 20  
 import org.kuali.rice.krad.authorization.FieldRestriction;
 21  
 import org.kuali.rice.krad.bo.BusinessObject;
 22  
 import org.kuali.rice.krad.bo.Inactivatable;
 23  
 import org.kuali.rice.krad.bo.PersistableBusinessObject;
 24  
 import org.kuali.rice.krad.datadictionary.CollectionDefinitionI;
 25  
 import org.kuali.rice.krad.datadictionary.FieldDefinition;
 26  
 import org.kuali.rice.krad.datadictionary.FieldDefinitionI;
 27  
 import org.kuali.rice.krad.datadictionary.InquiryCollectionDefinition;
 28  
 import org.kuali.rice.krad.datadictionary.InquirySectionDefinition;
 29  
 import org.kuali.rice.krad.datadictionary.InquirySubSectionHeaderDefinition;
 30  
 import org.kuali.rice.krad.datadictionary.MaintainableCollectionDefinition;
 31  
 import org.kuali.rice.krad.datadictionary.MaintainableFieldDefinition;
 32  
 import org.kuali.rice.krad.datadictionary.MaintainableItemDefinition;
 33  
 import org.kuali.rice.krad.datadictionary.MaintainableSectionDefinition;
 34  
 import org.kuali.rice.krad.datadictionary.MaintainableSubSectionHeaderDefinition;
 35  
 import org.kuali.rice.krad.datadictionary.SubSectionHeaderDefinitionI;
 36  
 import org.kuali.rice.krad.datadictionary.mask.MaskFormatter;
 37  
 import org.kuali.rice.krad.exception.ClassNotPersistableException;
 38  
 import org.kuali.rice.krad.inquiry.Inquirable;
 39  
 import org.kuali.rice.krad.inquiry.InquiryRestrictions;
 40  
 import org.kuali.rice.krad.lookup.LookupUtils;
 41  
 import org.kuali.rice.krad.maintenance.Maintainable;
 42  
 import org.kuali.rice.krad.service.BusinessObjectAuthorizationService;
 43  
 import org.kuali.rice.krad.service.DataDictionaryService;
 44  
 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
 45  
 import org.kuali.rice.krad.service.MaintenanceDocumentDictionaryService;
 46  
 import org.kuali.rice.krad.util.FieldUtils;
 47  
 import org.kuali.rice.krad.util.KRADConstants;
 48  
 import org.kuali.rice.krad.util.MaintenanceUtils;
 49  
 import org.kuali.rice.krad.util.ObjectUtils;
 50  
 
 51  
 import java.util.ArrayList;
 52  
 import java.util.Collection;
 53  
 import java.util.HashMap;
 54  
 import java.util.HashSet;
 55  
 import java.util.Iterator;
 56  
 import java.util.List;
 57  
 import java.util.Map;
 58  
 import java.util.Set;
 59  
 
 60  0
 public class SectionBridge {
 61  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SectionBridge.class);
 62  
     private static BusinessObjectAuthorizationService businessObjectAuthorizationService;
 63  
     private static BusinessObjectAuthorizationService getBusinessObjectAuthorizationService() {
 64  0
             if (businessObjectAuthorizationService == null) {
 65  0
                     businessObjectAuthorizationService = KRADServiceLocatorWeb.getBusinessObjectAuthorizationService();
 66  
             }
 67  0
             return businessObjectAuthorizationService;
 68  
     }
 69  
     private static DataDictionaryService dataDictionaryService;
 70  
     private static DataDictionaryService getDataDictionaryService() {
 71  0
             if (dataDictionaryService == null) {
 72  0
                     dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
 73  
             }
 74  0
             return dataDictionaryService;
 75  
     }
 76  
     private static MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService;
 77  
 
 78  
     /**
 79  
      * This method creates a Section for display on an Inquiry Screen.
 80  
      * 
 81  
      * @param sd The DD definition from which to construct the Section.
 82  
      * @param o The BusinessObject from which to populate the Section values.
 83  
      * @return A populated Section.
 84  
      */
 85  
     public static final Section toSection(Inquirable inquirable, InquirySectionDefinition sd, BusinessObject o, InquiryRestrictions auths) {
 86  0
         Section section = new Section();
 87  0
         section.setSectionId( sd.getId() );
 88  0
         section.setSectionTitle(sd.getTitle());
 89  0
         section.setRows(new ArrayList());
 90  0
         section.setDefaultOpen(sd.isDefaultOpen());
 91  
         
 92  0
         if (sd.getNumberOfColumns() != null) {
 93  0
             section.setNumberOfColumns(sd.getNumberOfColumns());
 94  
         }
 95  
         else {
 96  0
             section.setNumberOfColumns(KRADConstants.DEFAULT_NUM_OF_COLUMNS);
 97  
         }
 98  
 
 99  0
         List<Field> sectionFields = new ArrayList();
 100  0
         for (FieldDefinition fieldDefinition : sd.getInquiryFields()) {
 101  0
             List row = new ArrayList();
 102  
 
 103  0
             Field f = null;
 104  0
             if (fieldDefinition instanceof InquiryCollectionDefinition) {
 105  0
                 InquiryCollectionDefinition inquiryCollectionDefinition = (InquiryCollectionDefinition) fieldDefinition;
 106  
 
 107  0
                 List<Row> sectionRows = new ArrayList();
 108  0
                 sectionRows = getContainerRows(section, inquiryCollectionDefinition, o, null, null, new ArrayList(), new HashSet<String>(), new StringBuffer(section.getErrorKey()), inquiryCollectionDefinition.getNumberOfColumns(), inquirable);
 109  0
                 section.setRows(sectionRows);
 110  0
             }
 111  0
             else if (fieldDefinition instanceof InquirySubSectionHeaderDefinition) {
 112  0
                 f = createMaintainableSubSectionHeader((InquirySubSectionHeaderDefinition) fieldDefinition);
 113  
             }
 114  
             else {
 115  0
                 f = FieldBridge.toField(fieldDefinition, o, section);
 116  
             }
 117  
 
 118  0
             if (null != f) {
 119  0
                 sectionFields.add(f);
 120  
             }
 121  
 
 122  0
         }
 123  
 
 124  0
         if (!sectionFields.isEmpty()) {
 125  0
             section.setRows(FieldUtils.wrapFields(sectionFields, section.getNumberOfColumns()));
 126  
         }
 127  
 
 128  0
         applyInquirySectionAuthorizations(section, auths);
 129  
         
 130  0
         section.setRows(reArrangeRows(section.getRows(), section.getNumberOfColumns()));
 131  
         
 132  0
         return section;
 133  
     }
 134  
     
 135  
    
 136  
     private static final void applyInquirySectionAuthorizations(Section section, InquiryRestrictions inquiryRestrictions) {
 137  0
             applyInquiryRowsAuthorizations(section.getRows(), inquiryRestrictions);
 138  0
     }
 139  
     
 140  
     private static final void applyInquiryRowsAuthorizations(List<Row> rows, InquiryRestrictions inquiryRestrictions) {
 141  0
             for (Row row : rows) {
 142  0
                     List<Field> rowFields = row.getFields();
 143  0
                     for (Field field : rowFields) {
 144  0
                             applyInquiryFieldAuthorizations(field, inquiryRestrictions);
 145  
                     }
 146  0
             }
 147  0
     }
 148  
     
 149  
     protected static final void applyInquiryFieldAuthorizations(Field field, InquiryRestrictions inquiryRestrictions) {
 150  0
             if (Field.CONTAINER.equals(field.getFieldType())) {
 151  0
                     applyInquiryRowsAuthorizations(field.getContainerRows(), inquiryRestrictions);
 152  0
                     field.setContainerRows(reArrangeRows(field.getContainerRows(), field.getNumberOfColumnsForCollection()));
 153  
             }
 154  0
             else if (!Field.IMAGE_SUBMIT.equals(field.getFieldType())) {
 155  0
                     FieldRestriction fieldRestriction = inquiryRestrictions.getFieldRestriction(field.getPropertyName());
 156  0
                     if (fieldRestriction.isHidden()) {
 157  0
                             field.setFieldType(Field.HIDDEN);
 158  0
                             field.setPropertyValue(null);
 159  
                     }
 160  0
                     else if (fieldRestriction.isMasked()) {
 161  0
                     field.setSecure(true);
 162  0
                     MaskFormatter maskFormatter = fieldRestriction.getMaskFormatter();
 163  0
                     String displayMaskValue = maskFormatter.maskValue(field.getPropertyValue());
 164  0
                     field.setDisplayMaskValue(displayMaskValue);
 165  
                     // since it's an inquiry, let's wipe out the encrypted field value since we don't need to post it back
 166  0
                     field.setEncryptedValue("");
 167  
                     }
 168  
                }
 169  0
     }
 170  
     
 171  
     //This method is used to remove hidden fields (To fix JIRA KFSMI-2449)
 172  
     private static final List<Row> reArrangeRows(List<Row> rows, int numberOfColumns){
 173  0
             List<Row> rearrangedRows = new ArrayList<Row>();
 174  
             
 175  0
             for (Row row : rows) {
 176  0
                     List<Field> fields = new ArrayList<Field>();
 177  0
                     List<Field> rowFields = row.getFields();
 178  0
                     for (Field field : rowFields) {
 179  0
                             if(!Field.HIDDEN.equals(field.getFieldType()) && !Field.BLANK_SPACE.equals(field.getFieldType())){
 180  0
                                     fields.add(field);
 181  
                             }
 182  
                     }
 183  0
                     List<Row> rewrappedFieldRows = FieldUtils.wrapFields(fields, numberOfColumns);
 184  0
                     if (row.isHidden()) {
 185  0
                             for (Row rewrappedRow : rewrappedFieldRows) {
 186  0
                                     rewrappedRow.setHidden(true);
 187  
                             }
 188  
                     }
 189  0
                     rearrangedRows.addAll(rewrappedFieldRows);
 190  0
             }
 191  
             
 192  0
             return rearrangedRows;
 193  
     }
 194  
 
 195  
     
 196  
     /**
 197  
      * This method creates a Section for a MaintenanceDocument.
 198  
      * 
 199  
      * @param sd The DD definition of the Section.
 200  
      * @param o The BusinessObject from which the Section will be populated.
 201  
      * @param maintainable
 202  
      * @param maintenanceAction The action (new, newwithexisting, copy, edit, etc) requested from the UI.
 203  
      * @param autoFillDefaultValues Should default values be auto-filled?
 204  
      * @param autoFillBlankRequiredValues Should required values left blank on the UI be auto-filled?
 205  
      * @param displayedFieldNames What fields are displayed on the UI?
 206  
      * @return A populated Section.
 207  
      * @throws InstantiationException
 208  
      * @throws IllegalAccessException
 209  
      */
 210  
     public static final Section toSection(MaintainableSectionDefinition sd, BusinessObject o, Maintainable maintainable, Maintainable oldMaintainable, String maintenanceAction,  List<String> displayedFieldNames, Set<String> conditionallyRequiredMaintenanceFields) throws InstantiationException, IllegalAccessException {
 211  0
             Section section = new Section();
 212  
 
 213  0
         section.setSectionId( sd.getId() );
 214  0
         section.setSectionTitle(sd.getTitle());
 215  0
         section.setSectionClass(o.getClass());
 216  0
         section.setHidden( sd.isHidden() );
 217  0
         section.setDefaultOpen(sd.isDefaultOpen());
 218  0
         section.setHelpUrl(sd.getHelpUrl());
 219  
 
 220  
         // iterate through section maint items and contruct Field UI objects
 221  0
         Collection<MaintainableItemDefinition> maintItems = sd.getMaintainableItems();
 222  0
         List<Row> sectionRows = new ArrayList<Row>();
 223  0
         List<Field> sectionFields = new ArrayList<Field>();
 224  
 
 225  0
         for (MaintainableItemDefinition maintItem : maintItems) {
 226  0
             Field field = FieldBridge.toField(maintItem, sd, o, maintainable, section, displayedFieldNames, conditionallyRequiredMaintenanceFields);
 227  0
             boolean skipAdd = false;
 228  
 
 229  
             // if CollectionDefiniton, then have a many section
 230  0
             if (maintItem instanceof MaintainableCollectionDefinition) {
 231  0
                 MaintainableCollectionDefinition definition = (MaintainableCollectionDefinition) maintItem;
 232  0
                 section.getContainedCollectionNames().add(maintItem.getName());
 233  
 
 234  0
                 StringBuffer containerRowErrorKey = new StringBuffer();
 235  0
                 sectionRows = getContainerRows(section, definition, o, maintainable, oldMaintainable, displayedFieldNames, conditionallyRequiredMaintenanceFields, containerRowErrorKey, KRADConstants.DEFAULT_NUM_OF_COLUMNS, null);
 236  0
             } else if (maintItem instanceof MaintainableSubSectionHeaderDefinition) {
 237  0
                 MaintainableSubSectionHeaderDefinition definition = (MaintainableSubSectionHeaderDefinition) maintItem;
 238  0
                 field = createMaintainableSubSectionHeader(definition);
 239  
             }
 240  
 
 241  0
             if (!skipAdd) {
 242  0
                 sectionFields.add(field);
 243  
             }
 244  0
         }
 245  
 
 246  
         // populate field values from business object
 247  
         //if (o != null && !autoFillDefaultValues) {
 248  0
         if (o != null) {
 249  0
             sectionFields = FieldUtils.populateFieldsFromBusinessObject(sectionFields, o);
 250  
 
 251  
             /* if maintenance action is copy, clear out secure fields */
 252  0
             if (KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) {
 253  0
                 for (Iterator iterator = sectionFields.iterator(); iterator.hasNext();) {
 254  0
                     Field element = (Field) iterator.next();
 255  0
                     if (element.isSecure()) {
 256  0
                         element.setPropertyValue("");
 257  
                     }
 258  0
                 }
 259  
             }
 260  
         }
 261  
 
 262  0
         sectionRows.addAll(FieldUtils.wrapFields(sectionFields));
 263  0
         section.setRows(sectionRows);
 264  
 
 265  0
         return section;
 266  
 
 267  
     }
 268  
     
 269  
     
 270  
     /**
 271  
      * @see #getContainerRows(Section, CollectionDefinitionI, BusinessObject, Maintainable, List<String>, StringBuffer, String,
 272  
      *      boolean, int)
 273  
      */
 274  
     public static final List<Row> getContainerRows(Section s, CollectionDefinitionI collectionDefinition, BusinessObject o, Maintainable m, Maintainable oldMaintainable, List<String> displayedFieldNames, Set<String> conditionallyRequiredMaintenanceFields, StringBuffer containerRowErrorKey, int numberOfColumns, Inquirable inquirable) {
 275  0
         return getContainerRows(s, collectionDefinition, o, m, oldMaintainable, displayedFieldNames, conditionallyRequiredMaintenanceFields, containerRowErrorKey, "", false, numberOfColumns, inquirable);
 276  
     }
 277  
 
 278  
     /**
 279  
      * Builds a list of Rows with Fields of type containers for a many section.
 280  
      * 
 281  
      * @param s The Section containing the Collection/Container.
 282  
      * @param collectionDefinition The DD definition of the Collection.
 283  
      * @param o The BusinessObject from which the Container/Collection will be populated.
 284  
      * @param m The Maintainable for the BO (needed by some methods called on FieldBridge, FieldUtils etc.)
 285  
      * @param displayedFieldNames
 286  
      * @param containerRowErrorKey The error key for the Container/Collection.
 287  
      * @param parents
 288  
      * @param hideAdd Should the add line be added to the Container/Collection?
 289  
      * @param numberOfColumns In how many columns in the UI will the fields in the Container/Collection be shown?
 290  
      * @return
 291  
      */
 292  
      public static final List<Row> getContainerRows(Section s, CollectionDefinitionI collectionDefinition, BusinessObject o, Maintainable m, Maintainable oldMaintainable, List<String> displayedFieldNames, Set<String> conditionallyRequiredMaintenanceFields, StringBuffer containerRowErrorKey, String parents, boolean hideAdd, int numberOfColumns, Inquirable inquirable) {
 293  0
         List<Row> containerRows = new ArrayList<Row>();
 294  0
         List<Field> collFields = new ArrayList<Field>();
 295  
         
 296  0
         String collectionName = collectionDefinition.getName();
 297  
         
 298  
         // add the toggle inactive record display button for the collection
 299  0
         if (m != null && Inactivatable.class.isAssignableFrom(collectionDefinition.getBusinessObjectClass()) && StringUtils.isBlank(parents)) {
 300  0
             addShowInactiveButtonField(s, collectionName, !m.getShowInactiveRecords(collectionName));
 301  
         }
 302  0
         if (inquirable != null && Inactivatable.class.isAssignableFrom(collectionDefinition.getBusinessObjectClass()) && StringUtils.isBlank(parents)) {
 303  0
             addShowInactiveButtonField(s, collectionName, !inquirable.getShowInactiveRecords(collectionName));
 304  
         }
 305  
         
 306  
         // first need to populate the containerRows with the "new" form if available
 307  0
         if (!hideAdd) {
 308  0
             List<Field> newFormFields = new ArrayList<Field>();
 309  0
             if (collectionDefinition.getIncludeAddLine()) {
 310  
 
 311  
 
 312  0
                 newFormFields = FieldBridge.getNewFormFields(collectionDefinition, o, m, displayedFieldNames, conditionallyRequiredMaintenanceFields, containerRowErrorKey, parents, hideAdd, numberOfColumns);
 313  
 
 314  
 
 315  0
             } else if(collectionDefinition instanceof MaintainableCollectionDefinition) {
 316  0
                 MaintainableCollectionDefinition mcd = (MaintainableCollectionDefinition)collectionDefinition;
 317  0
                 if(FieldUtils.isCollectionMultipleLookupEnabled(mcd)) {
 318  
                     //do just the top line for collection if add is not allowed
 319  0
                   newFormFields = FieldBridge.constructContainerField(collectionDefinition, parents, o, hideAdd, numberOfColumns, mcd.getName(), new ArrayList<Field>());
 320  
                 }
 321  
             }
 322  0
             if (null != newFormFields) {
 323  0
                 containerRows.add(new Row(newFormFields));
 324  
             }
 325  
         }
 326  
 
 327  0
         Collection<? extends CollectionDefinitionI> collections = collectionDefinition.getCollections();
 328  0
         for (CollectionDefinitionI collection : collections) {
 329  0
             int subCollectionNumberOfColumn = numberOfColumns;
 330  0
             if (collectionDefinition instanceof InquiryCollectionDefinition) {
 331  0
                 InquiryCollectionDefinition icd = (InquiryCollectionDefinition) collection;
 332  0
                 if (icd.getNumberOfColumns() != null) {
 333  0
                     subCollectionNumberOfColumn = icd.getNumberOfColumns();
 334  
                 }
 335  
             }
 336  
             // no colNum for add rows
 337  0
              containerRows.addAll(getContainerRows(s, collection, o, m, oldMaintainable, displayedFieldNames, conditionallyRequiredMaintenanceFields, containerRowErrorKey, parents + collectionDefinition.getName() + ".", true, subCollectionNumberOfColumn, inquirable));
 338  0
         }
 339  
 
 340  
         // then we need to loop through the existing collection and add those fields
 341  0
         Collection<? extends FieldDefinitionI> collectionFields = collectionDefinition.getFields();
 342  
         // get label for collection
 343  0
         String collectionLabel = getDataDictionaryService().getCollectionLabel(o.getClass(), collectionDefinition.getName());
 344  
         
 345  
         // retrieve the summary label either from the override or from the DD
 346  0
         String collectionElementLabel = collectionDefinition.getSummaryTitle();
 347  0
         if (StringUtils.isEmpty(collectionElementLabel)) {
 348  0
             collectionElementLabel = getDataDictionaryService().getCollectionElementLabel(o.getClass().getName(), collectionDefinition.getName(), collectionDefinition.getBusinessObjectClass());
 349  
         }
 350  
 
 351  0
         boolean translateCodes = getMaintenanceDocumentDictionaryService().translateCodes(o.getClass());
 352  
 
 353  0
         if (o != null) {
 354  0
             if (PropertyUtils.isWriteable(o, collectionDefinition.getName()) && ObjectUtils.getPropertyValue(o, collectionDefinition.getName()) != null) {
 355  0
                 Object obj = ObjectUtils.getPropertyValue(o, collectionName);
 356  
                 
 357  0
                 Object oldObj = null;
 358  0
                 if (oldMaintainable != null && oldMaintainable.getBusinessObject() != null) {
 359  0
                     oldObj = ObjectUtils.getPropertyValue(oldMaintainable.getBusinessObject(), collectionName);
 360  
                 }
 361  
 
 362  0
                 if (obj instanceof List) {
 363  0
                     Map summaryFields = new HashMap();
 364  0
                     boolean hidableRowsPresent = false;
 365  0
                     for (int i = 0; i < ((List) obj).size(); i++) {
 366  0
                         BusinessObject lineBusinessObject = (BusinessObject) ((List) obj).get(i);
 367  
                         
 368  0
                         if (lineBusinessObject instanceof PersistableBusinessObject) {
 369  0
                                 ((PersistableBusinessObject) lineBusinessObject).refreshNonUpdateableReferences();
 370  
                         }
 371  
                         
 372  
                         /*
 373  
                          * Handle display of inactive records. The old maintainable is used to compare the old side (if it exists). If the row should not be displayed, it is set as
 374  
                          * hidden and will be handled in the maintenance rowDisplay.tag.   
 375  
                          */  
 376  0
                         boolean setRowHidden = false;
 377  0
                         BusinessObject oldLineBusinessObject = null;
 378  0
                         if (oldObj != null && ((List) oldObj).size() > i) {
 379  0
                             oldLineBusinessObject = (BusinessObject) ((List) oldObj).get(i);
 380  
                         }
 381  
                         
 382  0
                         if (lineBusinessObject instanceof Inactivatable && !((Inactivatable) lineBusinessObject).isActive()) {
 383  0
                             if (m != null) {
 384  
                                 // rendering a maint doc
 385  0
                                 if (!hidableRowsPresent) {
 386  0
                                     hidableRowsPresent = isRowHideableForMaintenanceDocument(lineBusinessObject, oldLineBusinessObject);
 387  
                                     }
 388  0
                                 setRowHidden = isRowHiddenForMaintenanceDocument(lineBusinessObject, oldLineBusinessObject, m, collectionName);
 389  
                                     }
 390  0
                             if (inquirable != null) {
 391  
                                 // rendering an inquiry screen
 392  0
                                 if (!hidableRowsPresent) {
 393  0
                                     hidableRowsPresent = isRowHideableForInquiry(lineBusinessObject);
 394  
                                 }
 395  0
                                 setRowHidden = isRowHiddenForInquiry(lineBusinessObject, inquirable, collectionName);
 396  
                             }
 397  
                         }
 398  
 
 399  0
                         collFields = new ArrayList<Field>();
 400  0
                         List<String> duplicateIdentificationFieldNames = new ArrayList<String>(); 
 401  
                         //We only need to do this if the collection definition is a maintainable collection definition, 
 402  
                         //don't need it for inquiry collection definition.
 403  0
                         if (collectionDefinition instanceof MaintainableCollectionDefinition) {
 404  0
                             Collection<MaintainableFieldDefinition> duplicateFieldDefs = ((MaintainableCollectionDefinition)collectionDefinition).getDuplicateIdentificationFields();
 405  0
                             for (MaintainableFieldDefinition eachFieldDef : duplicateFieldDefs) {
 406  0
                                 duplicateIdentificationFieldNames.add(eachFieldDef.getName());
 407  
                             }
 408  
                         }
 409  
                         
 410  0
                         for (FieldDefinitionI collectionField : collectionFields) {
 411  
 
 412  
                             // construct Field UI object from definition
 413  0
                             Field collField = FieldUtils.getPropertyField(collectionDefinition.getBusinessObjectClass(), collectionField.getName(), false);
 414  
                             
 415  0
                                             if (translateCodes) {
 416  0
                                                     FieldUtils.setAdditionalDisplayPropertyForCodes(lineBusinessObject.getClass(), collField.getPropertyName(), collField);
 417  
                                             }
 418  
                             
 419  0
                             FieldBridge.setupField(collField, collectionField, conditionallyRequiredMaintenanceFields);
 420  0
                             setPrimaryKeyFieldsReadOnly(collectionDefinition.getBusinessObjectClass(), collField);
 421  
 
 422  
                             //If the duplicateIdentificationFields were specified in the maint. doc. DD, we'll need
 423  
                             //to set the fields to be read only as well, in addition to the primary key fields.
 424  0
                             if (duplicateIdentificationFieldNames.size() > 0) {
 425  0
                                 setDuplicateIdentificationFieldsReadOnly(collField, duplicateIdentificationFieldNames);
 426  
                             }
 427  
                             
 428  0
                             FieldUtils.setInquiryURL(collField, lineBusinessObject, collectionField.getName());
 429  
                             // save the simple property name
 430  0
                             String name = collField.getPropertyName();
 431  
 
 432  
                             // prefix name for multi line (indexed)
 433  0
                             collField.setPropertyName(collectionDefinition.getName() + "[" + (new Integer(i)).toString() + "]." + collField.getPropertyName());
 434  
 
 435  
                             // commenting out codes for sub-collections show/hide for now
 436  
                             // subCollField.setContainerName(collectionDefinition.getName() + "["+i+"]" +"." +
 437  
                             // subCollectionDefinition.getName() + "[" + j + "]");
 438  
 
 439  0
                             if (collectionField instanceof MaintainableFieldDefinition) {
 440  0
                                 MaintenanceUtils.setFieldQuickfinder(lineBusinessObject, collectionDefinition.getName(), false, i, name, collField, displayedFieldNames, m, (MaintainableFieldDefinition) collectionField);
 441  0
                                 MaintenanceUtils.setFieldDirectInquiry(lineBusinessObject, name, (MaintainableFieldDefinition) collectionField, collField, displayedFieldNames);
 442  
                             } else {
 443  0
                                 LookupUtils.setFieldQuickfinder(lineBusinessObject, collectionDefinition.getName(), false, i, name, collField, displayedFieldNames, m);
 444  0
                                 LookupUtils.setFieldDirectInquiry(lineBusinessObject, name, collField);
 445  
                             }
 446  
 
 447  0
                             String propertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(lineBusinessObject, collectionField.getName());
 448  0
                             collField.setPropertyValue(propertyValue);
 449  
                             
 450  0
                                                         if (StringUtils.isNotBlank(collField.getAlternateDisplayPropertyName())) {
 451  0
                                                                 String alternateDisplayPropertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(lineBusinessObject,
 452  
                                                                                 collField.getAlternateDisplayPropertyName());
 453  0
                                                                 collField.setAlternateDisplayPropertyValue(alternateDisplayPropertyValue);
 454  
                                                         }
 455  
                                                         
 456  0
                                                         if (StringUtils.isNotBlank(collField.getAdditionalDisplayPropertyName())) {
 457  0
                                                                 String additionalDisplayPropertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(lineBusinessObject,
 458  
                                                                                 collField.getAdditionalDisplayPropertyName());
 459  0
                                                                 collField.setAdditionalDisplayPropertyValue(additionalDisplayPropertyValue);
 460  
                                                         }
 461  
                                 
 462  
                                                         //update user fields with universal id and/or name
 463  0
                                                         updateUserFields(collField, lineBusinessObject);
 464  
                                 
 465  
                             // the the field as read only (if appropriate)
 466  0
                             if (collectionField.isReadOnlyAfterAdd()) {
 467  0
                                 collField.setReadOnly(true);
 468  
                             }
 469  
 
 470  
                             // check if this is a summary field
 471  0
                             if (collectionDefinition.hasSummaryField(collectionField.getName())) {
 472  0
                                 summaryFields.put(collectionField.getName(), collField);
 473  
                             }
 474  
 
 475  0
                             collFields.add(collField);
 476  0
                         }
 477  
 
 478  
                         Field containerField;
 479  0
                         containerField = FieldUtils.constructContainerField(
 480  
                                 KRADConstants.EDIT_PREFIX + "[" + (new Integer(i)).toString() + "]", collectionLabel + " " + (i + 1), collFields, numberOfColumns);
 481  
                         // why is this only on collections and not subcollections any significance or just oversight?
 482  0
                         containerField.setContainerName(collectionDefinition.getName() + "[" + (new Integer(i)).toString() + "].");
 483  
 
 484  
                         /* If the collection line is pending (meaning added by this document) the isNewCollectionRecord will be set to true. In this
 485  
                            case we give an option to delete the line. The parameters for the delete action method are embedded into the button name. */
 486  0
                         if (lineBusinessObject instanceof PersistableBusinessObject && 
 487  
                                         (((PersistableBusinessObject) lineBusinessObject).isNewCollectionRecord() 
 488  
                                                         || collectionDefinition.isAlwaysAllowCollectionDeletion())) {
 489  0
                             containerField.getContainerRows().add(new Row(getDeleteRowButtonField(parents + collectionDefinition.getName(), (new Integer(i)).toString())));
 490  
                         }
 491  
 
 492  0
                         if (StringUtils.isNotEmpty(collectionElementLabel)) {
 493  
                             //We don't want to associate any indexes to the containerElementName anymore so that
 494  
                             //when the element is deleted, the currentTabIndex won't be associated with the
 495  
                             //wrong tab for the remaining tab.
 496  
                             //containerField.setContainerElementName(collectionElementLabel + " " + (i + 1));
 497  0
                             containerField.setContainerElementName(collectionElementLabel);
 498  
                             // reorder summaryFields to make sure they are in the order specified in the summary section
 499  0
                             List orderedSummaryFields = getSummaryFields(summaryFields, collectionDefinition);
 500  0
                             containerField.setContainerDisplayFields(orderedSummaryFields);
 501  
                         }
 502  
                         
 503  0
                         Row containerRow = new Row(containerField);
 504  0
                         if (setRowHidden) {
 505  0
                             containerRow.setHidden(true);
 506  
                         }
 507  0
                         containerRows.add(containerRow);
 508  
                         
 509  
                         
 510  
 
 511  0
                         Collection<? extends CollectionDefinitionI> subCollections = collectionDefinition.getCollections();
 512  0
                         List<Field> subCollFields = new ArrayList<Field>();
 513  
 
 514  0
                         summaryFields = new HashMap();
 515  
                         // iterate over the subCollections directly on this collection
 516  0
                         for (CollectionDefinitionI subCollection : subCollections) {
 517  0
                             Collection<? extends FieldDefinitionI> subCollectionFields = subCollection.getFields();
 518  0
                             int subCollectionNumberOfColumns = numberOfColumns;
 519  
 
 520  0
                             if (!s.getContainedCollectionNames().contains(collectionDefinition.getName() + "." + subCollection.getName())) {
 521  0
                                 s.getContainedCollectionNames().add(collectionDefinition.getName() + "." + subCollection.getName());
 522  
                             }
 523  
 
 524  0
                             if (subCollection instanceof InquiryCollectionDefinition) {
 525  0
                                 InquiryCollectionDefinition icd = (InquiryCollectionDefinition) subCollection;
 526  0
                                 if (icd.getNumberOfColumns() != null) {
 527  0
                                     subCollectionNumberOfColumns = icd.getNumberOfColumns();
 528  
                                 }
 529  
                             }
 530  
                             // get label for collection
 531  0
                             String subCollectionLabel = getDataDictionaryService().getCollectionLabel(o.getClass(), subCollection.getName());
 532  
 
 533  
                             // retrieve the summary label either from the override or from the DD
 534  0
                             String subCollectionElementLabel = subCollection.getSummaryTitle();
 535  0
                             if (StringUtils.isEmpty(subCollectionElementLabel)) {
 536  0
                                 subCollectionElementLabel = getDataDictionaryService().getCollectionElementLabel(o.getClass().getName(), subCollection.getName(), subCollection.getBusinessObjectClass());
 537  
                             }
 538  
                             // make sure it's really a collection (i.e. list)
 539  
 
 540  0
                             String subCollectionName = subCollection.getName();
 541  0
                             Object subObj = ObjectUtils.getPropertyValue(lineBusinessObject, subCollectionName);
 542  
                             
 543  0
                             Object oldSubObj = null;
 544  0
                             if (oldLineBusinessObject != null) {
 545  0
                                 oldSubObj = ObjectUtils.getPropertyValue(oldLineBusinessObject, subCollectionName);
 546  
                             }
 547  
                             
 548  0
                             if (subObj instanceof List) {
 549  
                                 /* recursively call this method to get the add row and exisiting members of the subCollections subcollections containerRows.addAll(getContainerRows(subCollectionDefinition,
 550  
                                    displayedFieldNames,containerRowErrorKey, parents+collectionDefinition.getName()+"["+i+"]"+".","[0]",false, subCollectionNumberOfColumn)); */
 551  0
                                 containerField.getContainerRows().addAll(getContainerRows(s, subCollection, o, m, oldMaintainable, displayedFieldNames, conditionallyRequiredMaintenanceFields, containerRowErrorKey, parents + collectionDefinition.getName() + "[" + i + "]" + ".", false, subCollectionNumberOfColumns, inquirable));
 552  
                              
 553  
                                 // iterate over the fields
 554  0
                                 for (int j = 0; j < ((List) subObj).size(); j++) {
 555  0
                                     BusinessObject lineSubBusinessObject = (BusinessObject) ((List) subObj).get(j);
 556  
                                     
 557  0
                                     if (lineSubBusinessObject instanceof PersistableBusinessObject) {
 558  0
                                             ((PersistableBusinessObject) lineSubBusinessObject).refreshNonUpdateableReferences();
 559  
                                     }
 560  
                                     
 561  
                                     // determine if sub collection line is inactive and should be hidden
 562  0
                                     boolean setSubRowHidden = false;
 563  0
                                     if (lineSubBusinessObject instanceof Inactivatable && !((Inactivatable) lineSubBusinessObject).isActive()) {
 564  0
                                         if (oldSubObj != null) { 
 565  
                                             // get corresponding elements in both the new list and the old list
 566  0
                                             BusinessObject oldLineSubBusinessObject = (BusinessObject) ((List) oldSubObj).get(j);
 567  0
                                             if (m != null) {
 568  0
                                                     if (!hidableRowsPresent) {
 569  0
                                                         hidableRowsPresent = isRowHideableForMaintenanceDocument(lineSubBusinessObject, oldLineSubBusinessObject);
 570  
                                                 }
 571  0
                                                     setSubRowHidden = isRowHiddenForMaintenanceDocument(lineSubBusinessObject, oldLineSubBusinessObject, m, collectionName);
 572  
                                                 }
 573  
                                             }
 574  0
                                         if (inquirable != null) {
 575  0
                                             if (!hidableRowsPresent) {
 576  0
                                                 hidableRowsPresent = isRowHideableForInquiry(lineSubBusinessObject);
 577  
                                         }
 578  0
                                             setSubRowHidden = isRowHiddenForInquiry(lineSubBusinessObject, inquirable, collectionName);
 579  
                                     }
 580  
                                     }
 581  
 
 582  
                                     
 583  0
                                     subCollFields = new ArrayList<Field>();
 584  
                                     // construct field objects based on fields
 585  0
                                     for (FieldDefinitionI subCollectionField : subCollectionFields) {
 586  
 
 587  
                                         // construct Field UI object from definition
 588  0
                                         Field subCollField = FieldUtils.getPropertyField(subCollection.getBusinessObjectClass(), subCollectionField.getName(), false);
 589  
 
 590  0
                                         String subCollectionFullName = collectionDefinition.getName() + "[" + i + "]" + "." + subCollection.getName();
 591  
                                         
 592  0
                                                         if (translateCodes) {
 593  0
                                                                 FieldUtils.setAdditionalDisplayPropertyForCodes(lineSubBusinessObject.getClass(), subCollField.getPropertyName(), subCollField);
 594  
                                                         }
 595  
 
 596  0
                                         FieldBridge.setupField(subCollField, subCollectionField, conditionallyRequiredMaintenanceFields);
 597  0
                                         setPrimaryKeyFieldsReadOnly(subCollection.getBusinessObjectClass(), subCollField);
 598  
                                        
 599  
                                         // save the simple property name
 600  0
                                         String name = subCollField.getPropertyName();
 601  
 
 602  
                                         // prefix name for multi line (indexed)
 603  0
                                         subCollField.setPropertyName(subCollectionFullName + "[" + j + "]." + subCollField.getPropertyName());
 604  
 
 605  
                                         // commenting out codes for sub-collections show/hide for now
 606  0
                                         if (subCollectionField instanceof MaintainableFieldDefinition) {
 607  0
                                             MaintenanceUtils.setFieldQuickfinder(lineSubBusinessObject, subCollectionFullName, false, j, name, subCollField, displayedFieldNames, m, (MaintainableFieldDefinition) subCollectionField);
 608  0
                                             MaintenanceUtils.setFieldDirectInquiry(lineSubBusinessObject, subCollectionFullName, false, j, name, subCollField, displayedFieldNames, m, (MaintainableFieldDefinition) subCollectionField);
 609  
                                         } else {
 610  0
                                             LookupUtils.setFieldQuickfinder(lineSubBusinessObject, subCollectionFullName, false, j, name, subCollField, displayedFieldNames);
 611  0
                                             LookupUtils.setFieldDirectInquiry(lineBusinessObject, name, subCollField);
 612  
                                         }
 613  
 
 614  0
                                         String propertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(lineSubBusinessObject, subCollectionField.getName());
 615  0
                                         subCollField.setPropertyValue(propertyValue);
 616  
                                         
 617  0
                                                                     if (StringUtils.isNotBlank(subCollField.getAlternateDisplayPropertyName())) {
 618  0
                                                                             String alternateDisplayPropertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(lineSubBusinessObject,
 619  
                                                                                             subCollField.getAlternateDisplayPropertyName());
 620  0
                                                                             subCollField.setAlternateDisplayPropertyValue(alternateDisplayPropertyValue);
 621  
                                                                     }
 622  
                                         
 623  0
                                                                     if (StringUtils.isNotBlank(subCollField.getAdditionalDisplayPropertyName())) {
 624  0
                                                                             String additionalDisplayPropertyValue = ObjectUtils.getFormattedPropertyValueUsingDataDictionary(lineSubBusinessObject,
 625  
                                                                                             subCollField.getAdditionalDisplayPropertyName());
 626  0
                                                                             subCollField.setAdditionalDisplayPropertyValue(additionalDisplayPropertyValue);
 627  
                                                                     }
 628  
                                      
 629  
                                         // check if this is a summary field
 630  0
                                         if (subCollection.hasSummaryField(subCollectionField.getName())) {
 631  0
                                             summaryFields.put(subCollectionField.getName(), subCollField);
 632  
                                         }
 633  
 
 634  0
                                         if (subCollectionField.isReadOnlyAfterAdd()) {
 635  0
                                             subCollField.setReadOnly(true);
 636  
                                         }
 637  
 
 638  0
                                         subCollFields.add(subCollField);
 639  0
                                     }
 640  
 
 641  0
                                     Field subContainerField = FieldUtils.constructContainerField(
 642  
                                             KRADConstants.EDIT_PREFIX + "[" + (new Integer(j)).toString() + "]", subCollectionLabel, subCollFields);
 643  0
                                     if (lineSubBusinessObject instanceof PersistableBusinessObject && (((PersistableBusinessObject) lineSubBusinessObject).isNewCollectionRecord() || subCollection.isAlwaysAllowCollectionDeletion())) {
 644  0
                                         subContainerField.getContainerRows().add(new Row(getDeleteRowButtonField(parents + collectionDefinition.getName() + "[" + i + "]" + "." + subCollectionName, (new Integer(j)).toString())));
 645  
                                     }
 646  
 
 647  
                                     // summary line code
 648  0
                                     if (StringUtils.isNotEmpty(subCollectionElementLabel)) {
 649  
                                         //We don't want to associate any indexes to the containerElementName anymore so that
 650  
                                         //when the element is deleted, the currentTabIndex won't be associated with the
 651  
                                         //wrong tab for the remaining tab.
 652  
                                         //subContainerField.setContainerElementName(subCollectionElementLabel + " " + (j + 1));
 653  0
                                         subContainerField.setContainerElementName(collectionElementLabel + "-" + subCollectionElementLabel);
 654  
                                     }
 655  0
                                     subContainerField.setContainerName(collectionDefinition.getName() + "." + subCollectionName);
 656  0
                                     if (!summaryFields.isEmpty()) {
 657  
                                         // reorder summaryFields to make sure they are in the order specified in the summary section
 658  0
                                         List orderedSummaryFields = getSummaryFields(summaryFields, subCollection);
 659  0
                                         subContainerField.setContainerDisplayFields(orderedSummaryFields);
 660  
                                     }
 661  
                                     
 662  0
                                     Row subContainerRow = new Row(subContainerField);
 663  0
                                     if (setRowHidden || setSubRowHidden) {
 664  0
                                         subContainerRow.setHidden(true);
 665  
                                     }
 666  0
                                     containerField.getContainerRows().add(subContainerRow);
 667  
                                 }
 668  
                             }
 669  0
                         }
 670  
                     }
 671  0
                     if ( !hidableRowsPresent ) {
 672  0
                         s.setExtraButtonSource( "" );
 673  
                     }
 674  
                 }
 675  
             }
 676  
         }
 677  
         
 678  0
         return containerRows;
 679  
     }
 680  
 
 681  
     /**
 682  
       * Updates fields of type kualiuser sets the universal user id and/or name if required. 
 683  
       * 
 684  
       * @param field
 685  
       * @param businessObject
 686  
       */
 687  
      private static final void updateUserFields(Field field, BusinessObject businessObject){
 688  
          // for user fields, attempt to pull the principal ID and person's name from the source object
 689  0
          if ( field.getFieldType().equals(Field.KUALIUSER) ) {
 690  
              // this is supplemental, so catch and log any errors
 691  
              try {
 692  0
                  if ( StringUtils.isNotBlank(field.getUniversalIdAttributeName()) ) {
 693  0
                      Object principalId = ObjectUtils.getNestedValue(businessObject, field.getUniversalIdAttributeName());
 694  0
                      if ( principalId != null ) {
 695  0
                          field.setUniversalIdValue(principalId.toString());
 696  
                      }
 697  
                  }
 698  0
                  if ( StringUtils.isNotBlank(field.getPersonNameAttributeName()) ) {
 699  0
                      Object personName = ObjectUtils.getNestedValue(businessObject, field.getPersonNameAttributeName());
 700  0
                      if ( personName != null ) {
 701  0
                          field.setPersonNameValue( personName.toString() );
 702  
                      }
 703  
                  }
 704  0
              } catch ( Exception ex ) {
 705  0
                  LOG.warn( "Unable to get principal ID or person name property in SectionBridge.", ex );
 706  0
              }
 707  
          }
 708  0
      }
 709  
      
 710  
     /**
 711  
      * Helper method to build up a Field containing a delete button mapped up to remove the collection record identified by the
 712  
      * given collection name and index.
 713  
      * 
 714  
      * @param collectionName - name of the collection
 715  
      * @param rowIndex - index of the record to associate delete button
 716  
      * @return Field - of type IMAGE_SUBMIT
 717  
      */
 718  
     private static final Field getDeleteRowButtonField(String collectionName, String rowIndex) {
 719  0
         Field deleteButtonField = new Field();
 720  
 
 721  0
         String deleteButtonName = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.DELETE_LINE_METHOD + "." + collectionName + "." + KRADConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL + ".line" + rowIndex;
 722  0
         deleteButtonField.setPropertyName(deleteButtonName);
 723  0
         deleteButtonField.setFieldType(Field.IMAGE_SUBMIT);
 724  0
         deleteButtonField.setPropertyValue("images/tinybutton-delete1.gif");
 725  
 
 726  0
         return deleteButtonField;
 727  
     }
 728  
     
 729  
     /**
 730  
      * Helper method to build up the show inactive button source and place in the section.
 731  
      * 
 732  
      * @param section - section that will display the button
 733  
      * @param collectionName - name of the collection to toggle setting
 734  
      * @param showInactive - boolean indicating whether inactive rows should be displayed
 735  
      * @return Field - of type IMAGE_SUBMIT
 736  
      */
 737  
     private static final void addShowInactiveButtonField(Section section, String collectionName, boolean showInactive) {
 738  0
             String methodName = KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TOGGLE_INACTIVE_METHOD + "." + collectionName.replace( '.', '_' );
 739  0
         methodName += "." + KRADConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL + showInactive + ".anchorshowInactive." + collectionName + KRADConstants.METHOD_TO_CALL_BOPARM_RIGHT_DEL;
 740  
            
 741  0
         String imageSource = showInactive ? "tinybutton-showinact.gif" : "tinybutton-hideinact.gif";
 742  
 
 743  0
         String showInactiveButton = "property=" + methodName + ";src=" + imageSource + ";alt=show(hide) inactive" + ";title=show(hide) inactive";
 744  
 
 745  0
         section.setExtraButtonSource(showInactiveButton);
 746  0
     }
 747  
     
 748  
     /**
 749  
      * Retrieves the primary key property names for the given class. If the field's property is one of those keys, makes the field
 750  
      * read-only. This is called for collection lines. Since deletion is not allowed for existing lines, the pk fields must be
 751  
      * read-only, otherwise a user could change the pk value which would be equivalent to deleting the line and adding a new line.
 752  
      */
 753  
     private static final void setPrimaryKeyFieldsReadOnly(Class businessObjectClass, Field field) {
 754  
             try{
 755  
                     //TODO: Revisit this. Changing since getPrimaryKeys and listPrimaryKeyFieldNames are apparently same.
 756  
                     //May be we might want to replace listPrimaryKeyFieldNames with getPrimaryKeys... Not sure.
 757  0
                     List primaryKeyPropertyNames = 
 758  
                             KRADServiceLocatorWeb.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(businessObjectClass);
 759  0
                 if (primaryKeyPropertyNames.contains(field.getPropertyName())) {
 760  0
                     field.setReadOnly(true);
 761  
                 }
 762  0
             } catch(ClassNotPersistableException ex){
 763  
                     //Not all classes will be persistable in a collection. For e.g. externalizable business objects.
 764  0
                     LOG.info("Not persistable businessObjectClass: "+businessObjectClass+", field: "+field);
 765  0
             }
 766  0
     }
 767  
     
 768  
     private static void setDuplicateIdentificationFieldsReadOnly(Field field, List<String>duplicateIdentificationFieldNames) {
 769  0
         if (duplicateIdentificationFieldNames.contains(field.getPropertyName())) {
 770  0
             field.setReadOnly(true);
 771  
         }
 772  0
     }
 773  
 
 774  
     /**
 775  
      * This method returns an ordered list of fields.
 776  
      * 
 777  
      * @param collSummaryFields
 778  
      * @param collectionDefinition
 779  
      * @return
 780  
      */
 781  
     private static final List<Field> getSummaryFields(Map collSummaryFields, CollectionDefinitionI collectionDefinition) {
 782  0
         List<Field> orderedSummaryFields = new ArrayList<Field>();
 783  0
         for (FieldDefinitionI summaryField : collectionDefinition.getSummaryFields()) {
 784  0
             String name = summaryField.getName();
 785  0
             boolean found = false;
 786  0
             Field addField = (Field) collSummaryFields.get(name);
 787  0
             if (!(addField == null)) {
 788  0
                 orderedSummaryFields.add(addField);
 789  0
                 found = true;
 790  
             }
 791  
 
 792  0
             if (!found) {
 793  
                 // should we throw a real error here?
 794  0
                 LOG.error("summaryField " + summaryField + " not present in the list");
 795  
             }
 796  
 
 797  0
         }
 798  0
         return orderedSummaryFields;
 799  
     }
 800  
 
 801  
     /**
 802  
      * This is a helper method to create a sub section header
 803  
      * 
 804  
      * @param definition the MaintainableSubSectionHeaderDefinition that we'll use to create the sub section header
 805  
      * @return the Field, which is the sub section header
 806  
      */
 807  
     private static final Field createMaintainableSubSectionHeader(SubSectionHeaderDefinitionI definition) {
 808  0
         Field separatorField = new Field();
 809  0
         separatorField.setFieldLabel(definition.getName());
 810  0
         separatorField.setFieldType(Field.SUB_SECTION_SEPARATOR);
 811  0
         separatorField.setReadOnly(true);
 812  
 
 813  0
         return separatorField;
 814  
     }
 815  
     
 816  
     /**
 817  
      * Determines whether a business object is hidable on a maintenance document.  Hidable means that if the user chose to hide the inactive
 818  
      * elements in the collection in which the passed in BOs reside, then the BOs would be hidden
 819  
      * 
 820  
      * @param lineBusinessObject the BO in the new maintainable, should be of type {@link PersistableBusinessObject} and {@link Inquirable}
 821  
      * @param oldLineBusinessObject the corresponding BO in the old maintainable, should be of type {@link PersistableBusinessObject} and 
 822  
      * {@link Inquirable}
 823  
      * @return whether the BOs are eligible to be hidden if the user decides to hide them
 824  
      */
 825  
     protected static boolean isRowHideableForMaintenanceDocument(BusinessObject lineBusinessObject, BusinessObject oldLineBusinessObject) {
 826  0
         if (oldLineBusinessObject != null) {
 827  0
             if (((PersistableBusinessObject) lineBusinessObject).isNewCollectionRecord()) {
 828  
                 // new records are never hidden, regardless of active status
 829  0
                 return false;
 830  
 }
 831  0
             if (!((Inactivatable) lineBusinessObject).isActive() && !((Inactivatable) oldLineBusinessObject).isActive()) {
 832  
                 // records with an old and new collection elements of NOT active are eligible to be hidden
 833  0
                 return true;
 834  
             }
 835  
         }
 836  0
         return false;
 837  
     }
 838  
     /**
 839  
      * Determines whether a business object is hidden on a maintenance document.
 840  
      * 
 841  
      * @param lineBusinessObject the BO in the new maintainable, should be of type {@link PersistableBusinessObject}
 842  
      * @param oldLineBusinessObject the corresponding BO in the old maintainable
 843  
      * @param newMaintainable the new maintainable from the maintenace document
 844  
      * @param collectionName the name of the collection from which these BOs come
 845  
      * @return
 846  
      */
 847  
     protected static boolean isRowHiddenForMaintenanceDocument(BusinessObject lineBusinessObject, BusinessObject oldLineBusinessObject,
 848  
             Maintainable newMaintainable, String collectionName) {
 849  0
         return isRowHideableForMaintenanceDocument(lineBusinessObject, oldLineBusinessObject) && !newMaintainable.getShowInactiveRecords(collectionName);
 850  
     }
 851  
     
 852  
     /**
 853  
      * Determines whether a business object is hidable on an inquiry screen.  Hidable means that if the user chose to hide the inactive
 854  
      * elements in the collection in which the passed in BO resides, then the BO would be hidden
 855  
      * 
 856  
      * @param lineBusinessObject the collection element BO, should be of type {@link PersistableBusinessObject} and {@link Inquirable}
 857  
      * @return whether the BO is eligible to be hidden if the user decides to hide them
 858  
      */
 859  
     protected static boolean isRowHideableForInquiry(BusinessObject lineBusinessObject) {
 860  0
         return !((Inactivatable) lineBusinessObject).isActive();
 861  
     }
 862  
     
 863  
     /**
 864  
      * Determines whether a business object is hidden on an inquiry screen.
 865  
      * 
 866  
      * @param lineBusinessObject the BO in the collection, should be of type {@link PersistableBusinessObject} and {@link Inquirable}
 867  
      * @param inquirable the inquirable
 868  
      * @param collectionName the name of the collection from which the BO comes
 869  
      * @return true if the business object is to be hidden; false otherwise
 870  
      */
 871  
     protected static boolean isRowHiddenForInquiry(BusinessObject lineBusinessObject, Inquirable inquirable, String collectionName) {
 872  0
         return isRowHideableForInquiry(lineBusinessObject) && !inquirable.getShowInactiveRecords(collectionName);
 873  
     }
 874  
     
 875  
         public static MaintenanceDocumentDictionaryService getMaintenanceDocumentDictionaryService() {
 876  0
             if (maintenanceDocumentDictionaryService == null) {
 877  0
                     maintenanceDocumentDictionaryService = KRADServiceLocatorWeb.getMaintenanceDocumentDictionaryService();
 878  
             }
 879  0
                 return maintenanceDocumentDictionaryService; 
 880  
         }
 881  
 }
 882