001/** 002 * Copyright 2005-2018 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.util; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.commons.lang.StringUtils; 024import org.apache.commons.logging.Log; 025import org.apache.commons.logging.LogFactory; 026import org.kuali.rice.core.api.uif.RemotableAbstractWidget; 027import org.kuali.rice.core.api.uif.RemotableAttributeField; 028import org.kuali.rice.core.api.uif.RemotableCheckbox; 029import org.kuali.rice.core.api.uif.RemotableCheckboxGroup; 030import org.kuali.rice.core.api.uif.RemotableControlContract; 031import org.kuali.rice.core.api.uif.RemotableDatepicker; 032import org.kuali.rice.core.api.uif.RemotableHiddenInput; 033import org.kuali.rice.core.api.uif.RemotableQuickFinder; 034import org.kuali.rice.core.api.uif.RemotableRadioButtonGroup; 035import org.kuali.rice.core.api.uif.RemotableSelect; 036import org.kuali.rice.core.api.uif.RemotableSelectGroup; 037import org.kuali.rice.core.api.uif.RemotableTextExpand; 038import org.kuali.rice.core.api.uif.RemotableTextInput; 039import org.kuali.rice.core.api.uif.RemotableTextarea; 040import org.kuali.rice.core.api.util.ConcreteKeyValue; 041import org.kuali.rice.core.api.util.KeyValue; 042import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint; 043import org.kuali.rice.krad.keyvalues.KeyValuesFinder; 044import org.kuali.rice.krad.lookup.LookupInputField; 045import org.kuali.rice.krad.lookup.LookupView; 046import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 047import org.kuali.rice.krad.uif.UifConstants; 048import org.kuali.rice.krad.uif.component.Component; 049import org.kuali.rice.krad.uif.container.CollectionGroup; 050import org.kuali.rice.krad.uif.container.DialogGroup; 051import org.kuali.rice.krad.uif.container.Group; 052import org.kuali.rice.krad.uif.container.LinkGroup; 053import org.kuali.rice.krad.uif.container.PageGroup; 054import org.kuali.rice.krad.uif.container.TabGroup; 055import org.kuali.rice.krad.uif.container.TabNavigationGroup; 056import org.kuali.rice.krad.uif.container.TreeGroup; 057import org.kuali.rice.krad.uif.control.CheckboxControl; 058import org.kuali.rice.krad.uif.control.CheckboxGroupControl; 059import org.kuali.rice.krad.uif.control.Control; 060import org.kuali.rice.krad.uif.control.FileControl; 061import org.kuali.rice.krad.uif.control.GroupControl; 062import org.kuali.rice.krad.uif.control.HiddenControl; 063import org.kuali.rice.krad.uif.control.MultiValueControl; 064import org.kuali.rice.krad.uif.control.RadioGroupControl; 065import org.kuali.rice.krad.uif.control.SelectControl; 066import org.kuali.rice.krad.uif.control.SizedControl; 067import org.kuali.rice.krad.uif.control.TextAreaControl; 068import org.kuali.rice.krad.uif.control.TextControl; 069import org.kuali.rice.krad.uif.control.UserControl; 070import org.kuali.rice.krad.uif.element.Action; 071import org.kuali.rice.krad.uif.element.Header; 072import org.kuali.rice.krad.uif.element.Iframe; 073import org.kuali.rice.krad.uif.element.Image; 074import org.kuali.rice.krad.uif.element.Label; 075import org.kuali.rice.krad.uif.element.Message; 076import org.kuali.rice.krad.uif.element.ValidationMessages; 077import org.kuali.rice.krad.uif.field.DataField; 078import org.kuali.rice.krad.uif.field.FieldGroup; 079import org.kuali.rice.krad.uif.field.GenericField; 080import org.kuali.rice.krad.uif.field.ImageField; 081import org.kuali.rice.krad.uif.field.InputField; 082import org.kuali.rice.krad.uif.field.LinkField; 083import org.kuali.rice.krad.uif.field.MessageField; 084import org.kuali.rice.krad.uif.field.SpaceField; 085import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 086import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata; 087import org.kuali.rice.krad.uif.view.InquiryView; 088import org.kuali.rice.krad.uif.widget.Inquiry; 089import org.kuali.rice.krad.uif.widget.LightBox; 090import org.kuali.rice.krad.uif.widget.QuickFinder; 091 092/** 093 * Factory class for creating new UIF components from their base definitions in the dictionary. 094 * 095 * @author Kuali Rice Team (rice.collab@kuali.org) 096 */ 097public class ComponentFactory { 098 private static Log LOG = LogFactory.getLog(ComponentFactory.class); 099 100 public static final String TEXT_CONTROL = "Uif-TextControl"; 101 public static final String CHECKBOX_CONTROL = "Uif-CheckboxControl"; 102 public static final String HIDDEN_CONTROL = "Uif-HiddenControl"; 103 public static final String TEXTAREA_CONTROL = "Uif-TextAreaControl"; 104 public static final String SELECT_CONTROL = "Uif-DropdownControl"; 105 public static final String CHECKBOX_CONVERTED_RADIO_CONTROL = "Uif-CheckboxConvertedRadioControl"; 106 public static final String CHECKBOX_GROUP_CONTROL = "Uif-VerticalCheckboxesControl"; 107 public static final String CHECKBOX_GROUP_CONTROL_HORIZONTAL = "Uif-HorizontalCheckboxesControl"; 108 public static final String RADIO_GROUP_CONTROL = "Uif-VerticalRadioControl"; 109 public static final String RADIO_GROUP_CONTROL_HORIZONTAL = "Uif-HorizontalRadioControl"; 110 public static final String FILE_CONTROL = "Uif-FileControl"; 111 public static final String DATE_CONTROL = "Uif-DateControl"; 112 public static final String USER_CONTROL = "Uif-KimPersonControl"; 113 public static final String GROUP_CONTROL = "Uif-KimGroupControl"; 114 115 public static final String DATA_FIELD = "Uif-DataField"; 116 public static final String INPUT_FIELD = "Uif-InputField"; 117 public static final String LOOKUP_ACTIVE_INPUT_FIELD = "Uif-LookupActiveInputField"; 118 public static final String LOOKUP_INPUT_FIELD = "Uif-LookupCriteriaInputField"; 119 public static final String ERRORS_FIELD = "Uif-FieldValidationMessages"; 120 public static final String ACTION = "Uif-PrimaryActionButton"; 121 public static final String SECONDARY_ACTION = "Uif-SecondaryActionButton"; 122 public static final String ACTION_LINK = "Uif-ActionLink"; 123 public static final String LINK_FIELD = "Uif-LinkField"; 124 public static final String IFRAME = "Uif-Iframe"; 125 public static final String IMAGE_FIELD = "Uif-ImageField"; 126 public static final String SPACE_FIELD = "Uif-SpaceField"; 127 public static final String GENERIC_FIELD = "Uif-CustomTemplateField"; 128 public static final String IMAGE = "Uif-Image"; 129 public static final String LABEL = "Uif-Label"; 130 public static final String MESSAGE = "Uif-Message"; 131 public static final String MESSAGE_FIELD = "Uif-MessageField"; 132 public static final String COLLECTION_GROUPING_FIELD = "Uif-ColGroupingField"; 133 public static final String FIELD_GROUP = "Uif-VerticalFieldGroup"; 134 public static final String HORIZONTAL_FIELD_GROUP = "Uif-HorizontalFieldGroup"; 135 136 public static final String GROUP = "Uif-GroupBase"; 137 public static final String VERTICAL_BOX_GROUP = "Uif-VerticalBoxGroup"; 138 public static final String HORIZONTAL_BOX_GROUP = "Uif-HorizontalBoxGroup"; 139 public static final String VERTICAL_BOX_SECTION = "Uif-VerticalBoxSection"; 140 public static final String HORIZONTAL_BOX_SECTION = "Uif-HorizontalBoxSection"; 141 public static final String PAGE_GROUP = "Uif-Page"; 142 public static final String GROUP_GRID_LAYOUT = "Uif-GridSection"; 143 public static final String GROUP_WITH_DISCLOSURE_GRID_LAYOUT = "Uif-Disclosure-GridSection"; 144 public static final String GROUP_BODY_ONLY = "Uif-BoxGroupBase"; 145 public static final String GROUP_GRID_BODY_ONLY = "Uif-GridGroup"; 146 public static final String TAB_GROUP = "Uif-TabSection"; 147 public static final String NAVIGATION_GROUP = "Uif-NavigationGroupBase"; 148 public static final String TREE_GROUP = "Uif-TreeSection"; 149 public static final String LINK_GROUP = "Uif-LinkGroup"; 150 public static final String DIALOG_GROUP = "Uif-DialogGroup"; 151 public static final String COLLECTION_GROUP = "Uif-StackedCollectionSection"; 152 public static final String COLLECTION_WITH_DISCLOSURE_GROUP = "Uif-Disclosure-StackedCollectionSection"; 153 public static final String COLLECTION_GROUP_TABLE_LAYOUT = "Uif-TableCollectionSection"; 154 public static final String COLLECTION_WITH_DISCLOSURE_GROUP_TABLE_LAYOUT = "Uif-Disclosure-TableCollectionSection"; 155 156 public static final String LIST_GROUP = "Uif-ListCollectionSection"; 157 158 public static final String HEADER = "Uif-HeaderFieldBase"; 159 public static final String FOOTER = "Uif-FooterBase"; 160 public static final String FOOTER_SAVECLOSECANCEL = "Uif-FormPageFooter"; 161 162 public static final String CONSTRAINT_MESSAGE = "Uif-ConstraintMessage"; 163 public static final String INSTRUCTIONAL_MESSAGE = "Uif-InstructionalMessage"; 164 public static final String HELP_ACTION = "Uif-HelpAction"; 165 public static final String IMAGE_CAPTION_HEADER = "Uif-ImageCaptionHeader"; 166 public static final String IMAGE_CUTLINE_MESSAGE = "Uif-ImageCutineMessage"; 167 168 public static final String LIGHTBOX = "Uif-LightBox"; 169 public static final String QUICKFINDER = "Uif-QuickFinder"; 170 public static final String INQUIRY = "Uif-Inquiry"; 171 172 public static final String ADD_BLANK_LINE_ACTION = "Uif-AddBlankLineAction"; 173 public static final String ADD_WITH_DIALOG_ACTION = "Uif-AddWithDialogAction"; 174 public static final String ADD_LINE_DIALOG = "Uif-AddLineDialog"; 175 public static final String DIALOG_DISMISS_ACTION = "Uif-DialogDismissButton"; 176 public static final String EDIT_LINE_DIALOG = "Uif-EditLineDialog"; 177 public static final String EDIT_LINE_IN_DIALOG_ACTION = "Uif-EditLineInDialogAction"; 178 public static final String EDIT_LINE_IN_DIALOG_SAVE_ACTION = "Uif-EditLineInDialogSaveAction"; 179 180 public static final String SESSION_TIMEOUT_WARNING_DIALOG = "Uif-SessionTimeoutWarning-DialogGroup"; 181 public static final String SESSION_TIMEOUT_DIALOG = "Uif-SessionTimeout-DialogGroup"; 182 public static final String YES_NO_DIALOG = "Uif-DialogGroup-YesNo"; 183 184 public static final String INQUIRY_VIEW = "Uif-InquiryView"; 185 public static final String LOOKUP_VIEW = "Uif-LookupView"; 186 public static final String LOOKUP_CRITERIA_FIELD = "Uif-LookupCriteriaInputField"; 187 public static final String LOOKUP_CRITERIA_ACTIVE_INDICATOR_FIELD = "Uif-LookupActiveInputField"; 188 189 public static final String URL_INFO = "Uif-Url"; 190 191 private static Map<String, Component> cache = new HashMap<String, Component>(); 192 193 /** 194 * Returns a new {@link Component} instance for the given bean id from the spring factory. 195 * 196 * @param id id for the component in the view index 197 * @return Component new instance 198 */ 199 public static Component getNewInstanceForRefresh(ViewPostMetadata viewPostMetadata, String id) { 200 String baseId = (String) viewPostMetadata.getComponentPostMetadata(id) 201 .getData(UifConstants.PostMetadata.BASE_ID); 202 if (baseId == null) { 203 throw new RuntimeException( 204 "Cannot create new instance for refresh. Base id not found for component id: " + id); 205 } 206 207 Component component = (Component) KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryBean(baseId); 208 209 if (component != null) { 210 component = ComponentUtils.copy(component); 211 } 212 213 return component; 214 } 215 216 /** 217 * Returns a new {@link Component} instance for the given bean id from the spring factory. 218 * 219 * @param beanId id of the bean definition 220 * @return new component instance or null if no such component definition was found 221 */ 222 public static Component getNewComponentInstance(String beanId) { 223 Component component; 224 225 if (cache.containsKey(beanId)) { 226 component = cache.get(beanId); 227 } else { 228 component = (Component) KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryBean(beanId); 229 230 // clear id before returning so duplicates do not occur 231 component.setId(null); 232 233 // populate property expressions from expression graph 234 ViewLifecycle.getExpressionEvaluator().populatePropertyExpressionsFromGraph(component, true); 235 236 // TODO: preprocess? 237 // CopyUtils.preventModification(component); 238 239 synchronized (cache) { 240 cache.put(beanId, component); 241 } 242 } 243 244 component = ComponentUtils.copy(component); 245 246 return component; 247 } 248 249 /** 250 * Retrieves a new Text control instance from Spring (initialized by the bean definition 251 * with the given id) 252 * 253 * @return TextControl 254 */ 255 public static TextControl getTextControl() { 256 return (TextControl) getNewComponentInstance(TEXT_CONTROL); 257 } 258 259 /** 260 * Retrieves a new Text area control instance from Spring (initialized by the bean definition 261 * with the given id) 262 * 263 * @return TextAreaControl 264 */ 265 public static TextAreaControl getTextAreaControl() { 266 return (TextAreaControl) getNewComponentInstance(TEXTAREA_CONTROL); 267 } 268 269 /** 270 * Retrieves a new checkbox control instance from Spring (initialized by the bean definition 271 * with the given id) 272 * 273 * @return CheckboxControl 274 */ 275 public static CheckboxControl getCheckboxControl() { 276 return (CheckboxControl) getNewComponentInstance(CHECKBOX_CONTROL); 277 } 278 279 /** 280 * Retrieves a new hidden control instance from Spring (initialized by the bean definition 281 * with the given id) 282 * 283 * @return HiddenControl 284 */ 285 public static HiddenControl getHiddenControl() { 286 return (HiddenControl) getNewComponentInstance(HIDDEN_CONTROL); 287 } 288 289 /** 290 * Retrieves a new select control instance from Spring (initialized by the bean definition 291 * with the given id) 292 * 293 * @return SelectControl 294 */ 295 public static SelectControl getSelectControl() { 296 return (SelectControl) getNewComponentInstance(SELECT_CONTROL); 297 } 298 299 /** 300 * Retrieves a new checkbox group control instance from Spring (initialized by the bean definition 301 * with the given id) 302 * 303 * <p> 304 * Return checkbox group set for vertical orientation 305 * </p> 306 * 307 * @return CheckboxGroupControl 308 */ 309 public static CheckboxGroupControl getCheckboxGroupControl() { 310 return (CheckboxGroupControl) getNewComponentInstance(CHECKBOX_GROUP_CONTROL); 311 } 312 313 /** 314 * Retrieves a new checkbox group control instance from Spring (initialized by the bean definition 315 * with the given id) 316 * 317 * <p> 318 * Return checkbox group set for horizontal orientation 319 * </p> 320 * 321 * @return CheckboxGroupControl 322 */ 323 public static CheckboxGroupControl getCheckboxGroupControlHorizontal() { 324 return (CheckboxGroupControl) getNewComponentInstance(CHECKBOX_GROUP_CONTROL_HORIZONTAL); 325 } 326 327 /** 328 * Retrieves a new radio group control instance from Spring (initialized by the bean definition 329 * with the given id) 330 * 331 * <p> 332 * Return radio group set for vertical orientation 333 * </p> 334 * 335 * @return RadioGroupControl 336 */ 337 public static RadioGroupControl getRadioGroupControl() { 338 return (RadioGroupControl) getNewComponentInstance(RADIO_GROUP_CONTROL); 339 } 340 341 /** 342 * Retrieves a new radio group control instance from Spring (initialized by the bean definition 343 * with the given id) 344 * 345 * <p> 346 * Return radio group set for horizontal orientation 347 * </p> 348 * 349 * @return RadioGroupControl 350 */ 351 public static RadioGroupControl getRadioGroupControlHorizontal() { 352 return (RadioGroupControl) getNewComponentInstance(RADIO_GROUP_CONTROL_HORIZONTAL); 353 } 354 355 /** 356 * Retrieves a new file control instance from Spring (initialized by the bean definition 357 * with the given id) 358 * 359 * @return FileControl 360 */ 361 public static FileControl getFileControl() { 362 return (FileControl) getNewComponentInstance(FILE_CONTROL); 363 } 364 365 /** 366 * Retrieves a new text control instance from Spring (initialized by the bean definition 367 * with the given id) configured for a date (enabled data picker) 368 * 369 * @return TextControl 370 */ 371 public static TextControl getDateControl() { 372 return (TextControl) getNewComponentInstance(DATE_CONTROL); 373 } 374 375 /** 376 * Retrieves a new text control instance from Spring (initialized by the bean definition 377 * with the given id) configured for KIM user input 378 * 379 * @return TextControl 380 */ 381 public static UserControl getUserControl() { 382 return (UserControl) getNewComponentInstance(USER_CONTROL); 383 } 384 385 /** 386 * Retrieves a new text control instance from Spring (initialized by the bean definition 387 * with the given id) configured for KIM group input 388 * 389 * @return TextControl 390 */ 391 public static GroupControl getGroupControl() { 392 return (GroupControl) getNewComponentInstance(GROUP_CONTROL); 393 } 394 395 /** 396 * Retrieves a new data field instance from Spring (initialized by the bean definition 397 * with the given id) 398 * 399 * @return DataField 400 */ 401 public static DataField getDataField() { 402 return (DataField) getNewComponentInstance(DATA_FIELD); 403 } 404 405 /** 406 * Retrieves a new data field instance from Spring (initialized by the bean definition 407 * with the given id) and sets the property name and label to the given parameters 408 * 409 * @param propertyName name of the property the data field should bind to 410 * @param label label for the field 411 * @return DataField 412 */ 413 public static DataField getDataField(String propertyName, String label) { 414 DataField field = (DataField) getNewComponentInstance(DATA_FIELD); 415 416 field.setPropertyName(propertyName); 417 field.setLabel(label); 418 419 return field; 420 } 421 422 /** 423 * Retrieves a new input field instance from Spring (initialized by the bean definition 424 * with the given id) 425 * 426 * @return InputField 427 */ 428 public static InputField getInputField() { 429 return (InputField) getNewComponentInstance(INPUT_FIELD); 430 } 431 432 /** 433 * Retrieves a new input field instance from Spring (initialized by the bean definition 434 * with the given id) and sets the property name and label to the given parameters 435 * 436 * @param propertyName name of the property the input field should bind to 437 * @param label label for the field 438 * @return InputField 439 */ 440 public static InputField getInputField(String propertyName, String label) { 441 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 442 443 field.setPropertyName(propertyName); 444 field.setLabel(label); 445 446 return field; 447 } 448 449 /** 450 * Retrieves a new input field instance from Spring (initialized by the bean definition 451 * with the given id) and sets the property name, control, and label to the given parameters 452 * 453 * @param propertyName name of the property the input field should bind to 454 * @param label label for the field 455 * @param controlType enum that identifies the type of control to create for the input field 456 * @return InputField 457 */ 458 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType) { 459 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 460 461 field.setPropertyName(propertyName); 462 field.setLabel(label); 463 field.setControl(getControl(controlType)); 464 465 return field; 466 } 467 468 /** 469 * Retrieves a new input field instance from Spring (initialized by the bean definition 470 * with the given id) and sets the property name, control, defaultValue, and label to the given parameters 471 * 472 * @param propertyName name of the property the input field should bind to 473 * @param label label for the field 474 * @param controlType enum that identifies the type of control to create for the input field 475 * @param defaultValue default value for the property backing the input field 476 * @return InputField 477 */ 478 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 479 String defaultValue) { 480 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 481 482 field.setPropertyName(propertyName); 483 field.setLabel(label); 484 field.setControl(getControl(controlType)); 485 field.setDefaultValue(defaultValue); 486 487 return field; 488 } 489 490 /** 491 * Retrieves a new input field instance from Spring (initialized by the bean definition 492 * with the given id) and sets the property name, control, options finder, and label to the given parameters 493 * 494 * @param propertyName name of the property the input field should bind to 495 * @param label label for the field 496 * @param controlType enum that identifies the type of control to create for the input field 497 * @param optionsFinderClass class that will provide options for the control (assume control type is multi-value) 498 * @return InputField 499 */ 500 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 501 Class<? extends KeyValuesFinder> optionsFinderClass) { 502 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 503 504 field.setPropertyName(propertyName); 505 field.setLabel(label); 506 field.setControl(getControl(controlType)); 507 field.setOptionsFinderClass(optionsFinderClass); 508 509 return field; 510 } 511 512 /** 513 * Retrieves a new input field instance from Spring (initialized by the bean definition 514 * with the given id) and sets the property name, control, options, and label to the given parameters 515 * 516 * @param propertyName name of the property the input field should bind to 517 * @param label label for the field 518 * @param controlType enum that identifies the type of control to create for the input field 519 * @param options list of key value objects to set as the controls options 520 * @return InputField 521 */ 522 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 523 List<KeyValue> options) { 524 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 525 526 field.setPropertyName(propertyName); 527 field.setLabel(label); 528 529 Control control = getControl(controlType); 530 if (control instanceof MultiValueControl) { 531 ((MultiValueControl) control).setOptions(options); 532 } else { 533 throw new RuntimeException("Control is not instance of multi-value control, cannot set options"); 534 } 535 536 return field; 537 } 538 539 /** 540 * Retrieves a new input field instance from Spring (initialized by the bean definition 541 * with the given id) and sets the property name, control, size, min and max length, 542 * and label to the given parameters 543 * 544 * @param propertyName name of the property the input field should bind to 545 * @param label label for the field 546 * @param controlType enum that identifies the type of control to create for the input field 547 * @param size size for the control 548 * @param maxLength max length for the field's value (also used for the control) 549 * @param minLength min length for the field's value (also used for the control) 550 * @return InputField 551 */ 552 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 553 int size, int maxLength, int minLength) { 554 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 555 556 field.setPropertyName(propertyName); 557 field.setLabel(label); 558 559 Control control = getControl(controlType); 560 if (control instanceof SizedControl) { 561 ((SizedControl) control).setSize(size); 562 } else { 563 throw new RuntimeException("Control does not support the size property"); 564 } 565 566 field.setMaxLength(maxLength); 567 field.setMinLength(minLength); 568 569 return field; 570 } 571 572 /** 573 * Builds a new <code>InputField</code> from the properties set on the 574 * given <code>RemotableAttributeField</code> 575 * 576 * <p> 577 * Note the returned InputField will not be initialized yet. Its state will be that of the initial 578 * object returned from the UIF dictionary with the properties set from the remotable attribute field, thus it 579 * is really just a more configuration complete field 580 * </p> 581 * 582 * @param remotableField field defined by a remove attribute 583 * 584 * @return AttributeField instance built from remotable field 585 */ 586 public static InputField translateRemotableField(RemotableAttributeField remotableField) { 587 InputField inputField = getInputField(); 588 589 inputField.setPropertyName(remotableField.getName()); 590 inputField.setShortLabel(remotableField.getShortLabel()); 591 inputField.setLabel(remotableField.getLongLabel()); 592 inputField.setConstraintText(remotableField.getConstraintText()); 593 inputField.setUppercaseValue(remotableField.isForceUpperCase()); 594 inputField.setMinLength(remotableField.getMinLength()); 595 inputField.setMaxLength(remotableField.getMaxLength()); 596 597 // why are exclusive min and max strings? 598 if (remotableField.getMinValue() != null) { 599 inputField.setExclusiveMin(remotableField.getMinValue().toString()); 600 } 601 if (remotableField.getMaxValue() != null) { 602 inputField.setInclusiveMax(remotableField.getMaxValue().toString()); 603 } 604 inputField.setRequired(remotableField.isRequired()); 605 606 if ((remotableField.getDefaultValues() != null) && !remotableField.getDefaultValues().isEmpty()) { 607 inputField.setDefaultValue(remotableField.getDefaultValues().iterator().next()); 608 } 609 610 if (StringUtils.isNotBlank(remotableField.getRegexConstraint())) { 611 ValidCharactersConstraint constraint = new ValidCharactersConstraint(); 612 constraint.setValue(remotableField.getRegexConstraint()); 613 inputField.setValidCharactersConstraint(constraint); 614 // TODO: how to deal with remotable field regexContraintMsg? 615 } 616 617 RemotableDatepicker remotableDatepicker = null; 618 RemotableTextExpand remotableTextExpand = null; 619 RemotableQuickFinder remotableQuickFinder = null; 620 for (RemotableAbstractWidget remoteWidget : remotableField.getWidgets()) { 621 if (remoteWidget instanceof RemotableDatepicker) { 622 remotableDatepicker = (RemotableDatepicker) remoteWidget; 623 } else if (remoteWidget instanceof RemotableTextExpand) { 624 remotableTextExpand = (RemotableTextExpand) remoteWidget; 625 } else if (remoteWidget instanceof RemotableQuickFinder) { 626 remotableQuickFinder = (RemotableQuickFinder) remoteWidget; 627 } 628 } 629 630 if (remotableQuickFinder != null) { 631 if (inputField.getQuickfinder() == null) { 632 inputField.setQuickfinder(ComponentFactory.getQuickFinder()); 633 } 634 635 inputField.getQuickfinder().setBaseLookupUrl(remotableQuickFinder.getBaseLookupUrl()); 636 inputField.getQuickfinder().setDataObjectClassName(remotableQuickFinder.getDataObjectClass()); 637 inputField.getQuickfinder().setLookupParameters(remotableQuickFinder.getLookupParameters()); 638 inputField.getQuickfinder().setFieldConversions(remotableQuickFinder.getFieldConversions()); 639 } 640 641 if (remotableField.getControl() != null) { 642 Control control = null; 643 644 RemotableControlContract remotableControl = remotableField.getControl(); 645 if (remotableControl instanceof RemotableHiddenInput) { 646 control = getHiddenControl(); 647 } else if (remotableControl instanceof RemotableRadioButtonGroup) { 648 RemotableRadioButtonGroup remotableRadioButtonGroup = (RemotableRadioButtonGroup) remotableControl; 649 control = getRadioGroupControl(); 650 ((RadioGroupControl) control).setOptions(buildKeyValuePairs(remotableRadioButtonGroup.getKeyLabels())); 651 } else if (remotableControl instanceof RemotableSelect) { 652 RemotableSelect remotableSelect = (RemotableSelect) remotableControl; 653 control = getSelectControl(); 654 655 Map<String, String> keyLabels = new HashMap<String, String>(); 656 if ((remotableSelect.getGroups() != null) && (!remotableSelect.getGroups().isEmpty())) { 657 for (RemotableSelectGroup remotableSelectGroup : remotableSelect.getGroups()) { 658 keyLabels.putAll(remotableSelectGroup.getKeyLabels()); 659 } 660 } else { 661 keyLabels = remotableSelect.getKeyLabels(); 662 } 663 664 ((SelectControl) control).setOptions(buildKeyValuePairs(keyLabels)); 665 if (remotableSelect.getSize() != null) { 666 ((SelectControl) control).setSize(remotableSelect.getSize()); 667 } 668 ((SelectControl) control).setMultiple(remotableSelect.isMultiple()); 669 } else if (remotableControl instanceof RemotableCheckboxGroup) { 670 RemotableCheckboxGroup remotableCheckboxGroup = (RemotableCheckboxGroup) remotableControl; 671 control = getCheckboxGroupControl(); 672 ((CheckboxGroupControl) control).setOptions(buildKeyValuePairs(remotableCheckboxGroup.getKeyLabels())); 673 } else if (remotableControl instanceof RemotableCheckbox) { 674 control = getCheckboxControl(); 675 } else if (remotableControl instanceof RemotableTextarea) { 676 RemotableTextarea remotableTextarea = (RemotableTextarea) remotableControl; 677 control = getTextAreaControl(); 678 679 if (remotableTextExpand != null) { 680 ((TextAreaControl) control).setTextExpand(true); 681 } 682 ((TextAreaControl) control).setRows(remotableTextarea.getRows()); 683 ((TextAreaControl) control).setCols(remotableTextarea.getCols()); 684 ((TextAreaControl) control).setWatermarkText(remotableTextarea.getWatermark()); 685 686 } else if (remotableControl instanceof RemotableTextInput) { 687 RemotableTextInput remotableTextInput = (RemotableTextInput) remotableControl; 688 689 if (remotableDatepicker != null) { 690 control = getDateControl(); 691 } else { 692 control = getTextControl(); 693 } 694 695 if (remotableTextExpand != null) { 696 ((TextAreaControl) control).setTextExpand(true); 697 } 698 ((TextControl) control).setSize(remotableTextInput.getSize()); 699 ((TextControl) control).setWatermarkText(remotableTextInput.getWatermark()); 700 } 701 702 inputField.setControl(control); 703 } 704 705 return inputField; 706 } 707 708 /** 709 * For each remotable field in the given list creates a new {@link org.kuali.rice.krad.uif.field.InputField} 710 * instance and sets the 711 * corresponding properties from the remotable instance 712 * 713 * @param remotableFields list of remotable fields to translate 714 * @return List<AttributeField> list of attribute fields built from the remotable field properties 715 */ 716 public static List<InputField> translateRemotableFields(List<RemotableAttributeField> remotableFields) { 717 List<InputField> inputFields = new ArrayList<InputField>(); 718 719 for (RemotableAttributeField remotableField : remotableFields) { 720 inputFields.add(translateRemotableField(remotableField)); 721 } 722 723 return inputFields; 724 } 725 726 /** 727 * For each option in the given list, create a new {@link org.kuali.rice.core.api.util.KeyValue} instance 728 * 729 * @param optionsMap list of options 730 * @return List<KeyValue> list of key values built from the list of options 731 */ 732 protected static List<KeyValue> buildKeyValuePairs(Map<String, String> optionsMap) { 733 List<KeyValue> options = new ArrayList<KeyValue>(); 734 735 for (Map.Entry<String, String> optionEntry : optionsMap.entrySet()) { 736 KeyValue keyValue = new ConcreteKeyValue(optionEntry.getKey(), optionEntry.getValue()); 737 options.add(keyValue); 738 } 739 740 return options; 741 } 742 743 /** 744 * Gets the control 745 * 746 * @param controlType 747 * @return the control based on the control type 748 */ 749 protected static Control getControl(UifConstants.ControlType controlType) { 750 Control control = null; 751 switch (controlType) { 752 case CHECKBOX: 753 control = getCheckboxControl(); 754 break; 755 case CHECKBOXGROUP: 756 control = getCheckboxGroupControl(); 757 break; 758 case FILE: 759 control = getFileControl(); 760 break; 761 case GROUP: 762 control = getGroupControl(); 763 break; 764 case HIDDEN: 765 control = getHiddenControl(); 766 break; 767 case RADIOGROUP: 768 control = getRadioGroupControl(); 769 break; 770 case SELECT: 771 control = getSelectControl(); 772 break; 773 case TEXTAREA: 774 control = getTextAreaControl(); 775 break; 776 case TEXT: 777 control = getTextControl(); 778 break; 779 case USER: 780 control = getUserControl(); 781 break; 782 } 783 784 return control; 785 } 786 787 /** 788 * Gets the errors field 789 * 790 * @return ValidationMessages errors field 791 */ 792 public static ValidationMessages getErrorsField() { 793 return (ValidationMessages) getNewComponentInstance(ERRORS_FIELD); 794 } 795 796 /** 797 * Gets the action 798 * 799 * @return action 800 */ 801 public static Action getAction() { 802 return (Action) getNewComponentInstance(ACTION); 803 } 804 805 /** 806 * Returns an instance of a secondary action component. 807 * 808 * @return action 809 */ 810 public static Action getSecondaryAction() { 811 return (Action) getNewComponentInstance(SECONDARY_ACTION); 812 } 813 814 /** 815 * Gets the action link 816 * 817 * @return action link 818 */ 819 public static Action getActionLink() { 820 return (Action) getNewComponentInstance(ACTION_LINK); 821 } 822 823 /** 824 * Gets the link field 825 * 826 * @return link field 827 */ 828 public static LinkField getLinkField() { 829 return (LinkField) getNewComponentInstance(LINK_FIELD); 830 } 831 832 /** 833 * Gets the iframe 834 * 835 * @return iframe 836 */ 837 public static Iframe getIframe() { 838 return (Iframe) getNewComponentInstance(IFRAME); 839 } 840 841 /** 842 * Gets the image field 843 * 844 * @return image field 845 */ 846 public static ImageField getImageField() { 847 return (ImageField) getNewComponentInstance(IMAGE_FIELD); 848 } 849 850 /** 851 * Gets the image component 852 * 853 * @return image field 854 */ 855 public static Image getImage() { 856 return (Image) getNewComponentInstance(IMAGE); 857 } 858 859 /** 860 * Gets the space field 861 * 862 * @return space field 863 */ 864 public static SpaceField getSpaceField() { 865 return (SpaceField) getNewComponentInstance(SPACE_FIELD); 866 } 867 868 /** 869 * Gets the generic field 870 * 871 * @return generic field 872 */ 873 public static GenericField getGenericField() { 874 return (GenericField) getNewComponentInstance(GENERIC_FIELD); 875 } 876 877 /** 878 * Gets the label 879 * 880 * @return label 881 */ 882 public static Label getLabel() { 883 return (Label) getNewComponentInstance(LABEL); 884 } 885 886 /** 887 * Gets the message 888 * 889 * @return message 890 */ 891 public static Message getMessage() { 892 return (Message) getNewComponentInstance(MESSAGE); 893 } 894 895 /** 896 * Gets the message field 897 * 898 * @return message field 899 */ 900 public static MessageField getMessageField() { 901 return (MessageField) getNewComponentInstance(MESSAGE_FIELD); 902 } 903 904 /** 905 * Gets the collection grouping field 906 * 907 * @return message field 908 */ 909 public static MessageField getColGroupingField() { 910 return (MessageField) getNewComponentInstance(COLLECTION_GROUPING_FIELD); 911 } 912 913 /** 914 * Gets the field group 915 * 916 * @return field group 917 */ 918 public static FieldGroup getFieldGroup() { 919 return (FieldGroup) getNewComponentInstance(FIELD_GROUP); 920 } 921 922 /** 923 * Gets the horizontal field group 924 * 925 * @return horizontal field group 926 */ 927 public static FieldGroup getHorizontalFieldGroup() { 928 return (FieldGroup) getNewComponentInstance(HORIZONTAL_FIELD_GROUP); 929 } 930 931 /** 932 * Gets the group 933 * 934 * @return group 935 */ 936 public static Group getGroup() { 937 return (Group) getNewComponentInstance(GROUP); 938 } 939 940 /** 941 * Gets the vertical box group 942 * 943 * @return group 944 */ 945 public static Group getVerticalBoxGroup() { 946 return (Group) getNewComponentInstance(VERTICAL_BOX_GROUP); 947 } 948 949 /** 950 * Gets the horizontal box group 951 * 952 * @return group 953 */ 954 public static Group getHorizontalBoxGroup() { 955 return (Group) getNewComponentInstance(HORIZONTAL_BOX_GROUP); 956 } 957 958 /** 959 * Gets the vertical box section 960 * 961 * @return group 962 */ 963 public static Group getVerticalBoxSection() { 964 return (Group) getNewComponentInstance(VERTICAL_BOX_SECTION); 965 } 966 967 /** 968 * Gets the horizontal box section 969 * 970 * @return group 971 */ 972 public static Group getHorizontalBoxSection() { 973 return (Group) getNewComponentInstance(HORIZONTAL_BOX_SECTION); 974 } 975 976 /** 977 * Gets the page group 978 * 979 * @return page group 980 */ 981 public static PageGroup getPageGroup() { 982 return (PageGroup) getNewComponentInstance(PAGE_GROUP); 983 } 984 985 /** 986 * Gets the group grid layout 987 * 988 * @return group grid layout 989 */ 990 public static Group getGroupGridLayout() { 991 return (Group) getNewComponentInstance(GROUP_GRID_LAYOUT); 992 } 993 994 public static Group getGroupWithDisclosureGridLayout() { 995 return (Group) getNewComponentInstance(GROUP_WITH_DISCLOSURE_GRID_LAYOUT); 996 } 997 998 /** 999 * Gets the group body only 1000 * 1001 * @return group body only 1002 */ 1003 public static Group getGroupBodyOnly() { 1004 return (Group) getNewComponentInstance(GROUP_BODY_ONLY); 1005 } 1006 1007 /** 1008 * Gets the group grid body only 1009 * 1010 * @return group grid body only 1011 */ 1012 public static Group getGroupGridBodyOnly() { 1013 return (Group) getNewComponentInstance(GROUP_GRID_BODY_ONLY); 1014 } 1015 1016 /** 1017 * Gets the tab group 1018 * 1019 * @return tab group 1020 */ 1021 public static TabGroup getTabGroup() { 1022 return (TabGroup) getNewComponentInstance(TAB_GROUP); 1023 } 1024 1025 /** 1026 * Gets the navigation group 1027 * 1028 * @return navigation group 1029 */ 1030 public static TabNavigationGroup getNavigationGroup() { 1031 return (TabNavigationGroup) getNewComponentInstance(NAVIGATION_GROUP); 1032 } 1033 1034 /** 1035 * Gets the tree group 1036 * 1037 * @return tree group 1038 */ 1039 public static TreeGroup getTreeGroup() { 1040 return (TreeGroup) getNewComponentInstance(TREE_GROUP); 1041 } 1042 1043 /** 1044 * Gets the link group 1045 * 1046 * @return link group 1047 */ 1048 public static LinkGroup getLinkGroup() { 1049 return (LinkGroup) getNewComponentInstance(LINK_GROUP); 1050 } 1051 1052 /** 1053 * Gets the collection group 1054 * 1055 * @return collection group 1056 */ 1057 public static CollectionGroup getCollectionGroup() { 1058 return (CollectionGroup) getNewComponentInstance(COLLECTION_GROUP); 1059 } 1060 1061 /** 1062 * Gets the collection group with disclosure behavior 1063 * 1064 * @return collection group 1065 */ 1066 public static CollectionGroup getCollectionWithDisclosureGroup() { 1067 return (CollectionGroup) getNewComponentInstance(COLLECTION_WITH_DISCLOSURE_GROUP); 1068 } 1069 1070 /** 1071 * Gets the collection group table layout 1072 * 1073 * @return collection group table layout 1074 */ 1075 public static CollectionGroup getCollectionGroupTableLayout() { 1076 return (CollectionGroup) getNewComponentInstance(COLLECTION_GROUP_TABLE_LAYOUT); 1077 } 1078 1079 /** 1080 * Gets the collection group table layout with disclosure behavior 1081 * 1082 * @return collection group table layout 1083 */ 1084 public static CollectionGroup getCollectionWithDisclosureGroupTableLayout() { 1085 return (CollectionGroup) getNewComponentInstance(COLLECTION_WITH_DISCLOSURE_GROUP_TABLE_LAYOUT); 1086 } 1087 1088 /** 1089 * Gets the list group 1090 * 1091 * @return list group 1092 */ 1093 public static CollectionGroup getListGroup() { 1094 return (CollectionGroup) getNewComponentInstance(LIST_GROUP); 1095 } 1096 1097 /** 1098 * Gets the header 1099 * 1100 * @return header 1101 */ 1102 public static Header getHeader() { 1103 return (Header) getNewComponentInstance(HEADER); 1104 } 1105 1106 /** 1107 * Gets the footer 1108 * 1109 * @return footer 1110 */ 1111 public static Group getFooter() { 1112 return (Group) getNewComponentInstance(FOOTER); 1113 } 1114 1115 /** 1116 * Gets the footer save/close/cancel 1117 * 1118 * @return footer save/close/cancel 1119 */ 1120 public static Group getFooterSaveCloseCancel() { 1121 return (Group) getNewComponentInstance(FOOTER_SAVECLOSECANCEL); 1122 } 1123 1124 /** 1125 * Gets the default action component configured for help 1126 * 1127 * @return Action for help display 1128 */ 1129 public static Action getHelpAction() { 1130 return (Action) getNewComponentInstance(HELP_ACTION); 1131 } 1132 1133 /** 1134 * Gets the default constraint message configuration 1135 * 1136 * @return Message component for constraint messages 1137 */ 1138 public static Message getConstraintMessage() { 1139 return (Message) getNewComponentInstance(CONSTRAINT_MESSAGE); 1140 } 1141 1142 /** 1143 * Gets the default instructional message configuration 1144 * 1145 * @return Message component for instructional messages 1146 */ 1147 public static Message getInstructionalMessage() { 1148 return (Message) getNewComponentInstance(INSTRUCTIONAL_MESSAGE); 1149 } 1150 1151 /** 1152 * Gets the default image caption header configuration 1153 * 1154 * @return Header component for image caption headers 1155 */ 1156 public static Header getImageCaptionHeader() { 1157 return (Header) getNewComponentInstance(IMAGE_CAPTION_HEADER); 1158 } 1159 1160 /** 1161 * Gets the default image cutline message configuration 1162 * 1163 * @return Message component for image cutlines messages 1164 */ 1165 public static Message getImageCutlineMessage() { 1166 return (Message) getNewComponentInstance(IMAGE_CUTLINE_MESSAGE); 1167 } 1168 1169 /** 1170 * Gets the default lightbox configuration 1171 * 1172 * @return Lightbox component 1173 */ 1174 public static LightBox getLightBox() { 1175 return (LightBox) getNewComponentInstance(LIGHTBOX); 1176 } 1177 1178 /** 1179 * Gets the default quickfinder configuration 1180 * 1181 * @return QuickFinder component 1182 */ 1183 public static QuickFinder getQuickFinder() { 1184 return (QuickFinder) getNewComponentInstance(QUICKFINDER); 1185 } 1186 1187 /** 1188 * Gets the default inquiry configuration 1189 * 1190 * @return Inquiry component 1191 */ 1192 public static Inquiry getInquiry() { 1193 return (Inquiry) getNewComponentInstance(INQUIRY); 1194 } 1195 1196 /** 1197 * Gets an instance of the session timeout warning dialog 1198 * 1199 * @return instance of session timeout warning dialog 1200 */ 1201 public static DialogGroup getSessionTimeoutWarningDialog() { 1202 return (DialogGroup) getNewComponentInstance(SESSION_TIMEOUT_WARNING_DIALOG); 1203 } 1204 1205 /** 1206 * Gets an instance of the session timeout dialog 1207 * 1208 * @return instance of session timeout dialog 1209 */ 1210 public static DialogGroup getSessionTimeoutDialog() { 1211 return (DialogGroup) getNewComponentInstance(SESSION_TIMEOUT_DIALOG); 1212 } 1213 1214 /** 1215 * Gets an instance of the yes no dialog 1216 * 1217 * @return instance of yes no dialog 1218 */ 1219 public static DialogGroup getYesNoDialog() { 1220 return (DialogGroup) getNewComponentInstance(YES_NO_DIALOG); 1221 } 1222 1223 /** 1224 * Gets an instance of an UrlInfo 1225 * 1226 * @return instance of UrlInfo 1227 */ 1228 public static UrlInfo getUrlInfo() { 1229 return (UrlInfo) getNewComponentInstance(URL_INFO); 1230 } 1231 1232 /** 1233 * Gets an empty inquiry view configuration for population. 1234 * 1235 * @return InquiryView component 1236 */ 1237 public static InquiryView getInquiryView() { 1238 return (InquiryView) getNewComponentInstance(INQUIRY_VIEW); 1239 } 1240 1241 /** 1242 * Gets an empty lookup view configuration for population. 1243 * 1244 * @return LookupView component 1245 */ 1246 public static LookupView getLookupView() { 1247 return (LookupView) getNewComponentInstance(LOOKUP_VIEW); 1248 } 1249 1250 /** 1251 * Gets a component instance for an input field in the lookup criteria section 1252 * @return lookup input field instance 1253 */ 1254 public static LookupInputField getLookupCriteriaInputField() { 1255 return (LookupInputField) getNewComponentInstance(LOOKUP_CRITERIA_FIELD); 1256 } 1257 1258 /** 1259 * Gets a component instance for an input field for the active indicator 1260 * in the lookup criteria section 1261 * @return lookup input field instance 1262 */ 1263 public static LookupInputField getLookupCriteriaActiveIndicatorInputField() { 1264 return (LookupInputField) getNewComponentInstance(LOOKUP_CRITERIA_ACTIVE_INDICATOR_FIELD); 1265 } 1266}