001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.uif.container; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import org.apache.commons.lang.StringUtils; 022import org.kuali.rice.core.api.exception.RiceRuntimeException; 023import org.kuali.rice.krad.uif.UifConstants; 024import org.kuali.rice.krad.uif.UifParameters; 025import org.kuali.rice.krad.uif.component.BindingInfo; 026import org.kuali.rice.krad.uif.component.Component; 027import org.kuali.rice.krad.uif.component.ComponentSecurity; 028import org.kuali.rice.krad.uif.component.DataBinding; 029import org.kuali.rice.krad.uif.field.ActionField; 030import org.kuali.rice.krad.uif.field.DataField; 031import org.kuali.rice.krad.uif.field.DataFieldSecurity; 032import org.kuali.rice.krad.uif.field.Field; 033import org.kuali.rice.krad.uif.field.LabelField; 034import org.kuali.rice.krad.uif.util.ComponentUtils; 035import org.kuali.rice.krad.uif.view.View; 036import org.kuali.rice.krad.uif.widget.QuickFinder; 037 038/** 039 * Group that holds a collection of objects and configuration for presenting the 040 * collection in the UI. Supports functionality such as add line, line actions, 041 * and nested collections. 042 * 043 * <p> 044 * Note the standard header/footer can be used to give a header to the 045 * collection as a whole, or to provide actions that apply to the entire 046 * collection 047 * </p> 048 * 049 * <p> 050 * For binding purposes the binding path of each row field is indexed. The name 051 * property inherited from <code>ComponentBase</code> is used as the collection 052 * name. The collectionObjectClass property is used to lookup attributes from 053 * the data dictionary. 054 * </p> 055 * 056 * @author Kuali Rice Team (rice.collab@kuali.org) 057 */ 058public class CollectionGroup extends Group implements DataBinding { 059 private static final long serialVersionUID = -6496712566071542452L; 060 061 private Class<?> collectionObjectClass; 062 063 private String propertyName; 064 private BindingInfo bindingInfo; 065 066 private boolean renderAddLine; 067 private String addLinePropertyName; 068 private BindingInfo addLineBindingInfo; 069 private LabelField addLineLabelField; 070 private List<? extends Component> addLineFields; 071 private List<ActionField> addLineActionFields; 072 073 private boolean renderLineActions; 074 private List<ActionField> actionFields; 075 076 private boolean renderSelectField; 077 private String selectPropertyName; 078 079 private QuickFinder collectionLookup; 080 081 private boolean showHideInactiveButton; 082 private boolean showInactive; 083 private CollectionFilter activeCollectionFilter; 084 private List<CollectionFilter> filters; 085 086 private List<CollectionGroup> subCollections; 087 private String subCollectionSuffix; 088 089 private CollectionGroupBuilder collectionGroupBuilder; 090 091 public CollectionGroup() { 092 renderAddLine = true; 093 renderLineActions = true; 094 showInactive = false; 095 showHideInactiveButton = true; 096 renderSelectField = false; 097 098 filters = new ArrayList<CollectionFilter>(); 099 actionFields = new ArrayList<ActionField>(); 100 addLineFields = new ArrayList<Field>(); 101 addLineActionFields = new ArrayList<ActionField>(); 102 subCollections = new ArrayList<CollectionGroup>(); 103 } 104 105 /** 106 * The following actions are performed: 107 * 108 * <ul> 109 * <li>Set fieldBindModelPath to the collection model path (since the fields 110 * have to belong to the same model as the collection)</li> 111 * <li>Set defaults for binding</li> 112 * <li>Default add line field list to groups items list</li> 113 * <li>Sets default active collection filter if not set</li> 114 * <li>Sets the dictionary entry (if blank) on each of the items to the 115 * collection class</li> 116 * </ul> 117 * 118 * @see org.kuali.rice.krad.uif.component.ComponentBase#performInitialization(org.kuali.rice.krad.uif.view.View, 119 * java.lang.Object) 120 */ 121 @Override 122 public void performInitialization(View view, Object model) { 123 setFieldBindingObjectPath(getBindingInfo().getBindingObjectPath()); 124 125 super.performInitialization(view, model); 126 127 if (bindingInfo != null) { 128 bindingInfo.setDefaults(view, getPropertyName()); 129 } 130 131 if (addLineBindingInfo != null) { 132 // add line binds to model property 133 if (StringUtils.isNotBlank(addLinePropertyName)) { 134 addLineBindingInfo.setDefaults(view, getPropertyName()); 135 addLineBindingInfo.setBindingName(addLinePropertyName); 136 if (StringUtils.isNotBlank(getFieldBindByNamePrefix())) { 137 addLineBindingInfo.setBindByNamePrefix(getFieldBindByNamePrefix()); 138 } 139 } 140 } 141 142 for (Component item : getItems()) { 143 if (item instanceof DataField) { 144 DataField field = (DataField) item; 145 146 if (StringUtils.isBlank(field.getDictionaryObjectEntry())) { 147 field.setDictionaryObjectEntry(collectionObjectClass.getName()); 148 } 149 } 150 } 151 152 for (Component addLineField : addLineFields) { 153 if (addLineField instanceof DataField) { 154 DataField field = (DataField) addLineField; 155 156 if (StringUtils.isBlank(field.getDictionaryObjectEntry())) { 157 field.setDictionaryObjectEntry(collectionObjectClass.getName()); 158 } 159 } 160 } 161 162 if ((addLineFields == null) || addLineFields.isEmpty()) { 163 addLineFields = getItems(); 164 } 165 166 // if active collection filter not set use default 167 if (this.activeCollectionFilter == null) { 168 activeCollectionFilter = new ActiveCollectionFilter(); 169 } 170 171 // set static collection path on items 172 String collectionPath = ""; 173 if (StringUtils.isNotBlank(getBindingInfo().getCollectionPath())) { 174 collectionPath += getBindingInfo().getCollectionPath() + "."; 175 } 176 if (StringUtils.isNotBlank(getBindingInfo().getBindByNamePrefix())) { 177 collectionPath += getBindingInfo().getBindByNamePrefix() + "."; 178 } 179 collectionPath += getBindingInfo().getBindingName(); 180 181 List<DataField> collectionFields = ComponentUtils.getComponentsOfTypeDeep(getItems(), DataField.class); 182 for (DataField collectionField : collectionFields) { 183 collectionField.getBindingInfo().setCollectionPath(collectionPath); 184 } 185 186 List<DataField> addLineCollectionFields = ComponentUtils.getComponentsOfTypeDeep(addLineFields, DataField.class); 187 for (DataField collectionField : addLineCollectionFields) { 188 collectionField.getBindingInfo().setCollectionPath(collectionPath); 189 } 190 191 // add collection entry to abstract classes 192 if (!view.getAbstractTypeClasses().containsKey(collectionPath)) { 193 view.getAbstractTypeClasses().put(collectionPath, getCollectionObjectClass()); 194 } 195 196 // initialize container items and sub-collections (since they are not in 197 // child list) 198 for (Component item : getItems()) { 199 view.getViewHelperService().performComponentInitialization(view, model, item); 200 } 201 202 // initialize addLineFields 203 for (Component item : addLineFields) { 204 view.getViewHelperService().performComponentInitialization(view, model, item); 205 } 206 207 for (CollectionGroup collectionGroup : getSubCollections()) { 208 collectionGroup.getBindingInfo().setCollectionPath(collectionPath); 209 view.getViewHelperService().performComponentInitialization(view, model, collectionGroup); 210 } 211 } 212 213 /** 214 * Calls the configured <code>CollectionGroupBuilder</code> to build the 215 * necessary components based on the collection data 216 * 217 * @see org.kuali.rice.krad.uif.container.ContainerBase#performApplyModel(org.kuali.rice.krad.uif.view.View, 218 * java.lang.Object, org.kuali.rice.krad.uif.component.Component) 219 */ 220 @Override 221 public void performApplyModel(View view, Object model, Component parent) { 222 super.performApplyModel(view, model, parent); 223 224 pushCollectionGroupToReference(); 225 226 // if rendering the collection group, build out the lines 227 if (isRender()) { 228 getCollectionGroupBuilder().build(view, model, this); 229 } 230 231 // TODO: is this necessary to call again? 232 pushCollectionGroupToReference(); 233 } 234 235 /** 236 * Sets a reference in the context map for all nested components to the collection group 237 * instance, and sets name as parameter for an action fields in the group 238 */ 239 protected void pushCollectionGroupToReference() { 240 List<Component> components = this.getComponentsForLifecycle(); 241 242 ComponentUtils.pushObjectToContext(components, UifConstants.ContextVariableNames.COLLECTION_GROUP, this); 243 244 List<ActionField> actionFields = ComponentUtils.getComponentsOfTypeDeep(components, ActionField.class); 245 for (ActionField actionField : actionFields) { 246 actionField.addActionParameter(UifParameters.SELLECTED_COLLECTION_PATH, 247 this.getBindingInfo().getBindingPath()); 248 } 249 } 250 251 /** 252 * New collection lines are handled in the framework by maintaining a map on 253 * the form. The map contains as a key the collection name, and as value an 254 * instance of the collection type. An entry is created here for the 255 * collection represented by the <code>CollectionGroup</code> if an instance 256 * is not available (clearExistingLine will force a new instance). The given 257 * model must be a subclass of <code>UifFormBase</code> in order to find the 258 * Map. 259 * 260 * @param model - Model instance that contains the new collection lines Map 261 * @param clearExistingLine - boolean that indicates whether the line should be set to a 262 * new instance if it already exists 263 */ 264 public void initializeNewCollectionLine(View view, Object model, CollectionGroup collectionGroup, 265 boolean clearExistingLine) { 266 getCollectionGroupBuilder().initializeNewCollectionLine(view, model, collectionGroup, clearExistingLine); 267 } 268 269 /** 270 * @see org.kuali.rice.krad.uif.container.ContainerBase#getComponentsForLifecycle() 271 */ 272 @Override 273 public List<Component> getComponentsForLifecycle() { 274 List<Component> components = super.getComponentsForLifecycle(); 275 276 components.add(addLineLabelField); 277 components.add(collectionLookup); 278 279 // remove the containers items because we don't want them as children 280 // (they will become children of the layout manager as the rows are 281 // created) 282 for (Component item : getItems()) { 283 if (components.contains(item)) { 284 components.remove(item); 285 } 286 } 287 288 return components; 289 } 290 291 /** 292 * @see org.kuali.rice.krad.uif.component.Component#getComponentPrototypes() 293 */ 294 @Override 295 public List<Component> getComponentPrototypes() { 296 List<Component> components = super.getComponentPrototypes(); 297 298 components.addAll(actionFields); 299 components.addAll(addLineActionFields); 300 components.addAll(getItems()); 301 components.addAll(getSubCollections()); 302 components.addAll(addLineFields); 303 304 return components; 305 } 306 307 /** 308 * Object class the collection maintains. Used to get dictionary information 309 * in addition to creating new instances for the collection when necessary 310 * 311 * @return Class<?> collection object class 312 */ 313 public Class<?> getCollectionObjectClass() { 314 return this.collectionObjectClass; 315 } 316 317 /** 318 * Setter for the collection object class 319 * 320 * @param collectionObjectClass 321 */ 322 public void setCollectionObjectClass(Class<?> collectionObjectClass) { 323 this.collectionObjectClass = collectionObjectClass; 324 } 325 326 /** 327 * @see org.kuali.rice.krad.uif.component.DataBinding#getPropertyName() 328 */ 329 public String getPropertyName() { 330 return this.propertyName; 331 } 332 333 /** 334 * Setter for the collections property name 335 * 336 * @param propertyName 337 */ 338 public void setPropertyName(String propertyName) { 339 this.propertyName = propertyName; 340 } 341 342 /** 343 * Determines the binding path for the collection. Used to get the 344 * collection value from the model in addition to setting the binding path 345 * for the collection attributes 346 * 347 * @see org.kuali.rice.krad.uif.component.DataBinding#getBindingInfo() 348 */ 349 public BindingInfo getBindingInfo() { 350 return this.bindingInfo; 351 } 352 353 /** 354 * Setter for the binding info instance 355 * 356 * @param bindingInfo 357 */ 358 public void setBindingInfo(BindingInfo bindingInfo) { 359 this.bindingInfo = bindingInfo; 360 } 361 362 /** 363 * Action fields that should be rendered for each collection line. Example 364 * line action is the delete action 365 * 366 * @return List<ActionField> line action fields 367 */ 368 public List<ActionField> getActionFields() { 369 return this.actionFields; 370 } 371 372 /** 373 * Setter for the line action fields list 374 * 375 * @param actionFields 376 */ 377 public void setActionFields(List<ActionField> actionFields) { 378 this.actionFields = actionFields; 379 } 380 381 /** 382 * Indicates whether the action column for the collection should be rendered 383 * 384 * @return boolean true if the actions should be rendered, false if not 385 * @see #getActionFields() 386 */ 387 public boolean isRenderLineActions() { 388 return this.renderLineActions; 389 } 390 391 /** 392 * Setter for the render line actions indicator 393 * 394 * @param renderLineActions 395 */ 396 public void setRenderLineActions(boolean renderLineActions) { 397 this.renderLineActions = renderLineActions; 398 } 399 400 /** 401 * Indicates whether an add line should be rendered for the collection 402 * 403 * @return boolean true if add line should be rendered, false if it should 404 * not be 405 */ 406 public boolean isRenderAddLine() { 407 return this.renderAddLine; 408 } 409 410 /** 411 * Setter for the render add line indicator 412 * 413 * @param renderAddLine 414 */ 415 public void setRenderAddLine(boolean renderAddLine) { 416 this.renderAddLine = renderAddLine; 417 } 418 419 /** 420 * Convenience getter for the add line label field text. The text is used to 421 * label the add line when rendered and its placement depends on the 422 * <code>LayoutManager</code>. 423 * <p> 424 * For the <code>TableLayoutManager</code> the label appears in the sequence 425 * column to the left of the add line fields. For the 426 * <code>StackedLayoutManager</code> the label is placed into the group 427 * header for the line. 428 * </p> 429 * 430 * @return String add line label 431 */ 432 public String getAddLineLabel() { 433 if (getAddLineLabelField() != null) { 434 return getAddLineLabelField().getLabelText(); 435 } 436 437 return null; 438 } 439 440 /** 441 * Setter for the add line label text 442 * 443 * @param addLineLabel 444 */ 445 public void setAddLineLabel(String addLineLabel) { 446 if (getAddLineLabelField() != null) { 447 getAddLineLabelField().setLabelText(addLineLabel); 448 } 449 } 450 451 /** 452 * <code>LabelField</code> instance for the add line label 453 * 454 * @return LabelField add line label field 455 * @see #getAddLineLabel() 456 */ 457 public LabelField getAddLineLabelField() { 458 return this.addLineLabelField; 459 } 460 461 /** 462 * Setter for the <code>LabelField</code> instance for the add line label 463 * 464 * @param addLineLabelField 465 * @see #getAddLineLabel() 466 */ 467 public void setAddLineLabelField(LabelField addLineLabelField) { 468 this.addLineLabelField = addLineLabelField; 469 } 470 471 /** 472 * Name of the property that contains an instance for the add line. If set 473 * this is used with the binding info to create the path to the add line. 474 * Can be left blank in which case the framework will manage the add line 475 * instance in a generic map. 476 * 477 * @return String add line property name 478 */ 479 public String getAddLinePropertyName() { 480 return this.addLinePropertyName; 481 } 482 483 /** 484 * Setter for the add line property name 485 * 486 * @param addLinePropertyName 487 */ 488 public void setAddLinePropertyName(String addLinePropertyName) { 489 this.addLinePropertyName = addLinePropertyName; 490 } 491 492 /** 493 * <code>BindingInfo</code> instance for the add line property used to 494 * determine the full binding path. If add line name given 495 * {@link #getAddLineLabel()} then it is set as the binding name on the 496 * binding info. Add line label and binding info are not required, in which 497 * case the framework will manage the new add line instances through a 498 * generic map (model must extend UifFormBase) 499 * 500 * @return BindingInfo add line binding info 501 */ 502 public BindingInfo getAddLineBindingInfo() { 503 return this.addLineBindingInfo; 504 } 505 506 /** 507 * Setter for the add line binding info 508 * 509 * @param addLineBindingInfo 510 */ 511 public void setAddLineBindingInfo(BindingInfo addLineBindingInfo) { 512 this.addLineBindingInfo = addLineBindingInfo; 513 } 514 515 /** 516 * List of <code>Component</code> instances that should be rendered for the 517 * collection add line (if enabled). If not set, the default group's items 518 * list will be used 519 * 520 * @return List<? extends Component> add line field list 521 */ 522 public List<? extends Component> getAddLineFields() { 523 return this.addLineFields; 524 } 525 526 /** 527 * Setter for the add line field list 528 * 529 * @param addLineFields 530 */ 531 public void setAddLineFields(List<? extends Component> addLineFields) { 532 this.addLineFields = addLineFields; 533 } 534 535 /** 536 * Action fields that should be rendered for the add line. This is generally 537 * the add action (button) but can be configured to contain additional 538 * actions 539 * 540 * @return List<ActionField> add line action fields 541 */ 542 public List<ActionField> getAddLineActionFields() { 543 return this.addLineActionFields; 544 } 545 546 /** 547 * Setter for the add line action fields 548 * 549 * @param addLineActionFields 550 */ 551 public void setAddLineActionFields(List<ActionField> addLineActionFields) { 552 this.addLineActionFields = addLineActionFields; 553 } 554 555 /** 556 * Indicates whether lines of the collection group should be selected by rendering a 557 * field for each line that will allow selection 558 * 559 * <p> 560 * For example, having the select field enabled could allow selecting multiple lines from a search 561 * to return (multi-value lookup) 562 * </p> 563 * 564 * @return boolean true if select field should be rendered, false if not 565 */ 566 public boolean isRenderSelectField() { 567 return renderSelectField; 568 } 569 570 /** 571 * Setter for the render selected field indicator 572 * 573 * @param renderSelectField 574 */ 575 public void setRenderSelectField(boolean renderSelectField) { 576 this.renderSelectField = renderSelectField; 577 } 578 579 /** 580 * When {@link #isRenderSelectField()} is true, gives the name of the property the select field 581 * should bind to 582 * 583 * <p> 584 * Note if no prefix is given in the property name, such as 'form.', it is assumed the property is 585 * contained on the collection line. In this case the binding path to the collection line will be 586 * appended. In other cases, it is assumed the property is a list or set of String that will hold the 587 * selected identifier strings 588 * </p> 589 * 590 * <p> 591 * This property is not required. If not the set the framework will use a property contained on 592 * <code>UifFormBase</code> 593 * </p> 594 * 595 * @return String property name for select field 596 */ 597 public String getSelectPropertyName() { 598 return selectPropertyName; 599 } 600 601 /** 602 * Setter for the property name that will bind to the select field 603 * 604 * @param selectPropertyName 605 */ 606 public void setSelectPropertyName(String selectPropertyName) { 607 this.selectPropertyName = selectPropertyName; 608 } 609 610 /** 611 * Instance of the <code>QuickFinder</code> widget that configures a multi-value lookup for the collection 612 * 613 * <p> 614 * If the collection lookup is enabled (by the render property of the quick finder), {@link 615 * #getCollectionObjectClass()} will be used as the data object class for the lookup (if not set). Field 616 * conversions need to be set as usual and will be applied for each line returned 617 * </p> 618 * 619 * @return QuickFinder instance configured for the collection lookup 620 */ 621 public QuickFinder getCollectionLookup() { 622 return collectionLookup; 623 } 624 625 /** 626 * Setter for the collection lookup quickfinder instance 627 * 628 * @param collectionLookup 629 */ 630 public void setCollectionLookup(QuickFinder collectionLookup) { 631 this.collectionLookup = collectionLookup; 632 } 633 634 /** 635 * Indicates whether inactive collections lines should be displayed 636 * 637 * <p> 638 * Setting only applies when the collection line type implements the 639 * <code>Inactivatable</code> interface. If true and showInactive is 640 * set to false, the collection will be filtered to remove any items 641 * whose active status returns false 642 * </p> 643 * 644 * @return boolean true to show inactive records, false to not render inactive records 645 */ 646 public boolean isShowInactive() { 647 return showInactive; 648 } 649 650 /** 651 * Setter for the show inactive indicator 652 * 653 * @param showInactive boolean show inactive 654 */ 655 public void setShowInactive(boolean showInactive) { 656 this.showInactive = showInactive; 657 } 658 659 /** 660 * Collection filter instance for filtering the collection data when the 661 * showInactive flag is set to false 662 * 663 * @return CollectionFilter 664 */ 665 public CollectionFilter getActiveCollectionFilter() { 666 return activeCollectionFilter; 667 } 668 669 /** 670 * Setter for the collection filter to use for filter inactive records from the 671 * collection 672 * 673 * @param activeCollectionFilter - CollectionFilter instance 674 */ 675 public void setActiveCollectionFilter(CollectionFilter activeCollectionFilter) { 676 this.activeCollectionFilter = activeCollectionFilter; 677 } 678 679 /** 680 * List of {@link CollectionFilter} instances that should be invoked to filter the collection before 681 * displaying 682 * 683 * @return List<CollectionFilter> 684 */ 685 public List<CollectionFilter> getFilters() { 686 return filters; 687 } 688 689 /** 690 * Setter for the List of collection filters for which the collection will be filtered against 691 * 692 * @param filters 693 */ 694 public void setFilters(List<CollectionFilter> filters) { 695 this.filters = filters; 696 } 697 698 /** 699 * List of <code>CollectionGroup</code> instances that are sub-collections 700 * of the collection represented by this collection group 701 * 702 * @return List<CollectionGroup> sub collections 703 */ 704 public List<CollectionGroup> getSubCollections() { 705 return this.subCollections; 706 } 707 708 /** 709 * Setter for the sub collection list 710 * 711 * @param subCollections 712 */ 713 public void setSubCollections(List<CollectionGroup> subCollections) { 714 this.subCollections = subCollections; 715 } 716 717 /** 718 * Suffix for IDs that identifies the collection line the sub-collection belongs to 719 * 720 * <p> 721 * Built by the framework as the collection lines are being generated 722 * </p> 723 * 724 * @return String id suffix for sub-collection 725 */ 726 public String getSubCollectionSuffix() { 727 return subCollectionSuffix; 728 } 729 730 /** 731 * Setter for the sub-collection suffix (used by framework, should not be 732 * set in configuration) 733 * 734 * @param subCollectionSuffix 735 */ 736 public void setSubCollectionSuffix(String subCollectionSuffix) { 737 this.subCollectionSuffix = subCollectionSuffix; 738 } 739 740 /** 741 * Collection Security object that indicates what authorization (permissions) exist for the collection 742 * 743 * @return CollectionGroupSecurity instance 744 */ 745 public CollectionGroupSecurity getCollectionGroupSecurity() { 746 return (CollectionGroupSecurity) super.getComponentSecurity(); 747 } 748 749 /** 750 * Override to assert a {@link CollectionGroupSecurity} instance is set 751 * 752 * @param componentSecurity - instance of CollectionGroupSecurity 753 */ 754 @Override 755 public void setComponentSecurity(ComponentSecurity componentSecurity) { 756 if (!(componentSecurity instanceof CollectionGroupSecurity)) { 757 throw new RiceRuntimeException( 758 "Component security for CollectionGroup should be instance of CollectionGroupSecurity"); 759 } 760 761 super.setComponentSecurity(componentSecurity); 762 } 763 764 @Override 765 protected Class<? extends ComponentSecurity> getComponentSecurityClass() { 766 return CollectionGroupSecurity.class; 767 } 768 769 /** 770 * <code>CollectionGroupBuilder</code> instance that will build the 771 * components dynamically for the collection instance 772 * 773 * @return CollectionGroupBuilder instance 774 */ 775 public CollectionGroupBuilder getCollectionGroupBuilder() { 776 if (this.collectionGroupBuilder == null) { 777 this.collectionGroupBuilder = new CollectionGroupBuilder(); 778 } 779 return this.collectionGroupBuilder; 780 } 781 782 /** 783 * Setter for the collection group building instance 784 * 785 * @param collectionGroupBuilder 786 */ 787 public void setCollectionGroupBuilder(CollectionGroupBuilder collectionGroupBuilder) { 788 this.collectionGroupBuilder = collectionGroupBuilder; 789 } 790 791 /** 792 * @param showHideInactiveButton the showHideInactiveButton to set 793 */ 794 public void setShowHideInactiveButton(boolean showHideInactiveButton) { 795 this.showHideInactiveButton = showHideInactiveButton; 796 } 797 798 /** 799 * @return the showHideInactiveButton 800 */ 801 public boolean isShowHideInactiveButton() { 802 return showHideInactiveButton; 803 } 804 805}