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