001 /** 002 * Copyright 2005-2012 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 */ 016 package org.kuali.rice.krad.uif.util; 017 018 import org.apache.commons.lang.StringUtils; 019 import org.apache.commons.logging.Log; 020 import org.apache.commons.logging.LogFactory; 021 import org.kuali.rice.core.api.uif.RemotableAbstractWidget; 022 import org.kuali.rice.core.api.uif.RemotableAttributeField; 023 import org.kuali.rice.core.api.uif.RemotableCheckbox; 024 import org.kuali.rice.core.api.uif.RemotableCheckboxGroup; 025 import org.kuali.rice.core.api.uif.RemotableControlContract; 026 import org.kuali.rice.core.api.uif.RemotableDatepicker; 027 import org.kuali.rice.core.api.uif.RemotableHiddenInput; 028 import org.kuali.rice.core.api.uif.RemotableQuickFinder; 029 import org.kuali.rice.core.api.uif.RemotableRadioButtonGroup; 030 import org.kuali.rice.core.api.uif.RemotableSelect; 031 import org.kuali.rice.core.api.uif.RemotableSelectGroup; 032 import org.kuali.rice.core.api.uif.RemotableTextExpand; 033 import org.kuali.rice.core.api.uif.RemotableTextInput; 034 import org.kuali.rice.core.api.uif.RemotableTextarea; 035 import org.kuali.rice.core.api.util.ConcreteKeyValue; 036 import org.kuali.rice.core.api.util.KeyValue; 037 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint; 038 import org.kuali.rice.krad.keyvalues.KeyValuesFinder; 039 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 040 import org.kuali.rice.krad.uif.UifConstants; 041 import org.kuali.rice.krad.uif.container.CollectionGroup; 042 import org.kuali.rice.krad.uif.container.Group; 043 import org.kuali.rice.krad.uif.container.LinkGroup; 044 import org.kuali.rice.krad.uif.container.NavigationGroup; 045 import org.kuali.rice.krad.uif.container.PageGroup; 046 import org.kuali.rice.krad.uif.container.TabGroup; 047 import org.kuali.rice.krad.uif.container.TreeGroup; 048 import org.kuali.rice.krad.uif.control.CheckboxControl; 049 import org.kuali.rice.krad.uif.control.CheckboxGroupControl; 050 import org.kuali.rice.krad.uif.control.Control; 051 import org.kuali.rice.krad.uif.control.FileControl; 052 import org.kuali.rice.krad.uif.control.HiddenControl; 053 import org.kuali.rice.krad.uif.control.MultiValueControl; 054 import org.kuali.rice.krad.uif.control.RadioGroupControl; 055 import org.kuali.rice.krad.uif.control.SelectControl; 056 import org.kuali.rice.krad.uif.control.SizedControl; 057 import org.kuali.rice.krad.uif.control.TextAreaControl; 058 import org.kuali.rice.krad.uif.control.TextControl; 059 import org.kuali.rice.krad.uif.component.Component; 060 import org.kuali.rice.krad.uif.element.Action; 061 import org.kuali.rice.krad.uif.element.Header; 062 import org.kuali.rice.krad.uif.element.Iframe; 063 import org.kuali.rice.krad.uif.element.Image; 064 import org.kuali.rice.krad.uif.element.Label; 065 import org.kuali.rice.krad.uif.element.Message; 066 import org.kuali.rice.krad.uif.element.ValidationMessages; 067 import org.kuali.rice.krad.uif.field.DataField; 068 import org.kuali.rice.krad.uif.field.InputField; 069 import org.kuali.rice.krad.uif.field.MessageField; 070 import org.kuali.rice.krad.uif.field.SpaceField; 071 import org.kuali.rice.krad.uif.field.FieldGroup; 072 import org.kuali.rice.krad.uif.field.GenericField; 073 import org.kuali.rice.krad.uif.field.ImageField; 074 import org.kuali.rice.krad.uif.field.LinkField; 075 import org.kuali.rice.krad.uif.view.View; 076 077 import java.util.ArrayList; 078 import java.util.HashMap; 079 import java.util.List; 080 import java.util.Map; 081 082 /** 083 * Factory class for creating new UIF components from their base definitions 084 * in the dictionary 085 * 086 * @author Kuali Rice Team (rice.collab@kuali.org) 087 */ 088 public class ComponentFactory { 089 090 private static Log LOG = LogFactory.getLog(ComponentFactory.class); 091 092 protected static final String TEXT_CONTROL = "Uif-TextControl"; 093 protected static final String CHECKBOX_CONTROL = "Uif-CheckboxControl"; 094 protected static final String HIDDEN_CONTROL = "Uif-HiddenControl"; 095 protected static final String TEXTAREA_CONTROL = "Uif-TextAreaControl"; 096 protected static final String SELECT_CONTROL = "Uif-DropdownControl"; 097 protected static final String CHECKBOX_GROUP_CONTROL = "Uif-VerticalCheckboxesControl"; 098 protected static final String CHECKBOX_GROUP_CONTROL_HORIZONTAL = "Uif-HorizontalCheckboxesControl"; 099 protected static final String RADIO_GROUP_CONTROL = "Uif-VerticalRadioControl"; 100 protected static final String RADIO_GROUP_CONTROL_HORIZONTAL = "Uif-HorizontalRadioControl"; 101 protected static final String FILE_CONTROL = "Uif-FileControl"; 102 protected static final String DATE_CONTROL = "Uif-DateControl"; 103 protected static final String USER_CONTROL = "Uif-KimPersonControl"; 104 protected static final String GROUP_CONTROL = "Uif-KimGroupControl"; 105 106 protected static final String DATA_FIELD = "Uif-DataField"; 107 protected static final String INPUT_FIELD = "Uif-InputField"; 108 protected static final String ERRORS_FIELD = "Uif-FieldValidationMessages"; 109 protected static final String ACTION = "Uif-PrimaryActionButton"; 110 protected static final String ACTION_LINK = "Uif-ActionLink"; 111 protected static final String LINK_FIELD = "Uif-LinkField"; 112 protected static final String IFRAME = "Uif-Iframe"; 113 protected static final String IMAGE_FIELD = "Uif-ImageField"; 114 protected static final String SPACE_FIELD = "Uif-SpaceField"; 115 protected static final String GENERIC_FIELD = "Uif-CustomTemplateField"; 116 protected static final String IMAGE = "Uif-Image"; 117 protected static final String LABEL = "Uif-Label"; 118 protected static final String MESSAGE = "Uif-Message"; 119 protected static final String MESSAGE_FIELD = "Uif-MessageField"; 120 protected static final String FIELD_GROUP = "Uif-VerticalFieldGroup"; 121 protected static final String HORIZONTAL_FIELD_GROUP = "Uif-HorizontalFieldGroup"; 122 123 protected static final String GROUP = "Uif-BoxSection"; 124 protected static final String PAGE_GROUP = "Uif-Page"; 125 protected static final String GROUP_GRID_LAYOUT = "Uif-GridSection"; 126 protected static final String GROUP_BODY_ONLY = "Uif-BoxGroup"; 127 protected static final String GROUP_GRID_BODY_ONLY = "Uif-GridGroup"; 128 protected static final String TAB_GROUP = "Uif-TabSection"; 129 protected static final String NAVIGATION_GROUP = "Uif-NavigationGroupBase"; 130 protected static final String TREE_GROUP = "Uif-TreeSection"; 131 protected static final String LINK_GROUP = "Uif-LinkGroup"; 132 protected static final String COLLECTION_GROUP = "Uif-StackedCollectionSection"; 133 protected static final String COLLECTION_GROUP_TABLE_LAYOUT = "Uif-TableCollectionSection"; 134 protected static final String LIST_GROUP = "Uif-ListCollectionSection"; 135 136 protected static final String HEADER = "Uif-HeaderFieldBase"; 137 protected static final String FOOTER = "Uif-FooterBase"; 138 protected static final String FOOTER_SAVECLOSECANCEL = "Uif-FormPageFooter"; 139 140 protected static final String CONSTRAINT_MESSAGE = "Uif-ConstraintMessage"; 141 protected static final String INSTRUCTIONAL_MESSAGE = "Uif-InstructionalMessage"; 142 protected static final String HELP_ACTION = "Uif-HelpAction"; 143 protected static final String IMAGE_CAPTION_HEADER = "Uif-ImageCaptionHeader"; 144 protected static final String IMAGE_CUTLINE_MESSAGE = "Uif-ImageCutineMessage"; 145 146 private static Map<String, Component> cache = new HashMap<String, Component>(); 147 148 /** 149 * Gets a fresh copy of the component by the id passed in which used to look up the component in 150 * the view index, then retrieve a new instance with initial state configured using the factory id 151 * 152 * @param id - id for the component in the view index 153 * @return Component new instance 154 */ 155 public static Component getNewInstanceForRefresh(View view, String id) { 156 Component component = null; 157 Component origComponent = view.getViewIndex().getComponentById(id); 158 159 if (origComponent == null) { 160 throw new RuntimeException(id + " not found in view index try setting p:forceSessionPersistence=\"true\" in xml"); 161 } 162 163 if (view.getViewIndex().getInitialComponentStates().containsKey(origComponent.getBaseId())) { 164 component = view.getViewIndex().getInitialComponentStates().get(origComponent.getBaseId()); 165 LOG.debug("getNewInstanceForRefresh: id '" + id + "' was found in initialStates"); 166 } else { 167 component = (Component) KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryObject( 168 origComponent.getBaseId()); 169 LOG.debug("getNewInstanceForRefresh: id '" 170 + id 171 + "' was NOT found in initialStates. New one fetched from DD"); 172 } 173 174 if (component != null) { 175 component = ComponentUtils.copyObject(component); 176 component.setId(origComponent.getBaseId()); 177 } 178 179 return component; 180 } 181 182 /** 183 * Returns a new <code>Component</code> instance for the given bean id from the spring factory 184 * 185 * @param beanId - id of the bean definition 186 * @return new component instance or null if no such component definition was found 187 */ 188 public static Component getNewComponentInstance(String beanId) { 189 Component component = null; 190 if (cache.containsKey(beanId)) { 191 component = ComponentUtils.copy(cache.get(beanId)); 192 } else { 193 component = (Component) KRADServiceLocatorWeb.getDataDictionaryService().getDictionaryObject(beanId); 194 195 // clear id before returning so duplicates do not occur 196 component.setId(null); 197 component.setBaseId(null); 198 199 // populate property expressions from expression graph 200 ExpressionUtils.populatePropertyExpressionsFromGraph(component, true); 201 202 // add to cache 203 cache.put(beanId, ComponentUtils.copy(component)); 204 } 205 206 return component; 207 } 208 209 /** 210 * Retrieves a new Text control instance from Spring (initialized by the bean definition 211 * with the given id) 212 * 213 * @return TextControl 214 */ 215 public static TextControl getTextControl() { 216 return (TextControl) getNewComponentInstance(TEXT_CONTROL); 217 } 218 219 /** 220 * Retrieves a new Text area control instance from Spring (initialized by the bean definition 221 * with the given id) 222 * 223 * @return TextAreaControl 224 */ 225 public static TextAreaControl getTextAreaControl() { 226 return (TextAreaControl) getNewComponentInstance(TEXTAREA_CONTROL); 227 } 228 229 /** 230 * Retrieves a new checkbox control instance from Spring (initialized by the bean definition 231 * with the given id) 232 * 233 * @return CheckboxControl 234 */ 235 public static CheckboxControl getCheckboxControl() { 236 return (CheckboxControl) getNewComponentInstance(CHECKBOX_CONTROL); 237 } 238 239 /** 240 * Retrieves a new hidden control instance from Spring (initialized by the bean definition 241 * with the given id) 242 * 243 * @return HiddenControl 244 */ 245 public static HiddenControl getHiddenControl() { 246 return (HiddenControl) getNewComponentInstance(HIDDEN_CONTROL); 247 } 248 249 /** 250 * Retrieves a new select control instance from Spring (initialized by the bean definition 251 * with the given id) 252 * 253 * @return SelectControl 254 */ 255 public static SelectControl getSelectControl() { 256 return (SelectControl) getNewComponentInstance(SELECT_CONTROL); 257 } 258 259 /** 260 * Retrieves a new checkbox group control instance from Spring (initialized by the bean definition 261 * with the given id) 262 * 263 * <p> 264 * Return checkbox group set for vertical orientation 265 * </p> 266 * 267 * @return CheckboxGroupControl 268 */ 269 public static CheckboxGroupControl getCheckboxGroupControl() { 270 return (CheckboxGroupControl) getNewComponentInstance(CHECKBOX_GROUP_CONTROL); 271 } 272 273 /** 274 * Retrieves a new checkbox group control instance from Spring (initialized by the bean definition 275 * with the given id) 276 * 277 * <p> 278 * Return checkbox group set for horizontal orientation 279 * </p> 280 * 281 * @return CheckboxGroupControl 282 */ 283 public static CheckboxGroupControl getCheckboxGroupControlHorizontal() { 284 return (CheckboxGroupControl) getNewComponentInstance(CHECKBOX_GROUP_CONTROL_HORIZONTAL); 285 } 286 287 /** 288 * Retrieves a new radio group control instance from Spring (initialized by the bean definition 289 * with the given id) 290 * 291 * <p> 292 * Return radio group set for vertical orientation 293 * </p> 294 * 295 * @return RadioGroupControl 296 */ 297 public static RadioGroupControl getRadioGroupControl() { 298 return (RadioGroupControl) getNewComponentInstance(RADIO_GROUP_CONTROL); 299 } 300 301 /** 302 * Retrieves a new radio group control instance from Spring (initialized by the bean definition 303 * with the given id) 304 * 305 * <p> 306 * Return radio group set for horizontal orientation 307 * </p> 308 * 309 * @return RadioGroupControl 310 */ 311 public static RadioGroupControl getRadioGroupControlHorizontal() { 312 return (RadioGroupControl) getNewComponentInstance(RADIO_GROUP_CONTROL_HORIZONTAL); 313 } 314 315 /** 316 * Retrieves a new file control instance from Spring (initialized by the bean definition 317 * with the given id) 318 * 319 * @return FileControl 320 */ 321 public static FileControl getFileControl() { 322 return (FileControl) getNewComponentInstance(FILE_CONTROL); 323 } 324 325 /** 326 * Retrieves a new text control instance from Spring (initialized by the bean definition 327 * with the given id) configured for a date (enabled data picker) 328 * 329 * @return TextControl 330 */ 331 public static TextControl getDateControl() { 332 return (TextControl) getNewComponentInstance(DATE_CONTROL); 333 } 334 335 /** 336 * Retrieves a new text control instance from Spring (initialized by the bean definition 337 * with the given id) configured for KIM user input 338 * 339 * @return TextControl 340 */ 341 public static TextControl getUserControl() { 342 return (TextControl) getNewComponentInstance(USER_CONTROL); 343 } 344 345 /** 346 * Retrieves a new text control instance from Spring (initialized by the bean definition 347 * with the given id) configured for KIM group input 348 * 349 * @return TextControl 350 */ 351 public static TextControl getGroupControl() { 352 return (TextControl) getNewComponentInstance(GROUP_CONTROL); 353 } 354 355 /** 356 * Retrieves a new data field instance from Spring (initialized by the bean definition 357 * with the given id) 358 * 359 * @return DataField 360 */ 361 public static DataField getDataField() { 362 return (DataField) getNewComponentInstance(DATA_FIELD); 363 } 364 365 /** 366 * Retrieves a new data field instance from Spring (initialized by the bean definition 367 * with the given id) and sets the property name and label to the given parameters 368 * 369 * @param propertyName - name of the property the data field should bind to 370 * @param label - label for the field 371 * @return DataField 372 */ 373 public static DataField getDataField(String propertyName, String label) { 374 DataField field = (DataField) getNewComponentInstance(DATA_FIELD); 375 376 field.setPropertyName(propertyName); 377 field.setLabel(label); 378 379 return field; 380 } 381 382 /** 383 * Retrieves a new input field instance from Spring (initialized by the bean definition 384 * with the given id) 385 * 386 * @return InputField 387 */ 388 public static InputField getInputField() { 389 return (InputField) getNewComponentInstance(INPUT_FIELD); 390 } 391 392 /** 393 * Retrieves a new input field instance from Spring (initialized by the bean definition 394 * with the given id) and sets the property name and label to the given parameters 395 * 396 * @param propertyName - name of the property the input field should bind to 397 * @param label - label for the field 398 * @return InputField 399 */ 400 public static InputField getInputField(String propertyName, String label) { 401 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 402 403 field.setPropertyName(propertyName); 404 field.setLabel(label); 405 406 return field; 407 } 408 409 /** 410 * Retrieves a new input field instance from Spring (initialized by the bean definition 411 * with the given id) and sets the property name, control, and label to the given parameters 412 * 413 * @param propertyName - name of the property the input field should bind to 414 * @param label - label for the field 415 * @param controlType - enum that identifies the type of control to create for the input field 416 * @return InputField 417 */ 418 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType) { 419 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 420 421 field.setPropertyName(propertyName); 422 field.setLabel(label); 423 field.setControl(getControl(controlType)); 424 425 return field; 426 } 427 428 /** 429 * Retrieves a new input field instance from Spring (initialized by the bean definition 430 * with the given id) and sets the property name, control, defaultValue, and label to the given parameters 431 * 432 * @param propertyName - name of the property the input field should bind to 433 * @param label - label for the field 434 * @param controlType - enum that identifies the type of control to create for the input field 435 * @param defaultValue - default value for the property backing the input field 436 * @return InputField 437 */ 438 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 439 String defaultValue) { 440 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 441 442 field.setPropertyName(propertyName); 443 field.setLabel(label); 444 field.setControl(getControl(controlType)); 445 field.setDefaultValue(defaultValue); 446 447 return field; 448 } 449 450 /** 451 * Retrieves a new input field instance from Spring (initialized by the bean definition 452 * with the given id) and sets the property name, control, options finder, and label to the given parameters 453 * 454 * @param propertyName - name of the property the input field should bind to 455 * @param label - label for the field 456 * @param controlType - enum that identifies the type of control to create for the input field 457 * @param optionsFinderClass - class that will provide options for the control (assume control type is multi-value) 458 * @return InputField 459 */ 460 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 461 Class<? extends KeyValuesFinder> optionsFinderClass) { 462 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 463 464 field.setPropertyName(propertyName); 465 field.setLabel(label); 466 field.setControl(getControl(controlType)); 467 field.setOptionsFinderClass(optionsFinderClass); 468 469 return field; 470 } 471 472 /** 473 * Retrieves a new input field instance from Spring (initialized by the bean definition 474 * with the given id) and sets the property name, control, options, and label to the given parameters 475 * 476 * @param propertyName - name of the property the input field should bind to 477 * @param label - label for the field 478 * @param controlType - enum that identifies the type of control to create for the input field 479 * @param options - list of key value objects to set as the controls options 480 * @return InputField 481 */ 482 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 483 List<KeyValue> options) { 484 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 485 486 field.setPropertyName(propertyName); 487 field.setLabel(label); 488 489 Control control = getControl(controlType); 490 if (control instanceof MultiValueControl) { 491 ((MultiValueControl) control).setOptions(options); 492 } else { 493 throw new RuntimeException("Control is not instance of multi-value control, cannot set options"); 494 } 495 496 return field; 497 } 498 499 /** 500 * Retrieves a new input field instance from Spring (initialized by the bean definition 501 * with the given id) and sets the property name, control, size, min and max length, 502 * and label to the given parameters 503 * 504 * @param propertyName - name of the property the input field should bind to 505 * @param label - label for the field 506 * @param controlType - enum that identifies the type of control to create for the input field 507 * @param size - size for the control 508 * @param maxLength - max length for the field's value (also used for the control) 509 * @param minLength - min length for the field's value (also used for the control) 510 * @return InputField 511 */ 512 public static InputField getInputField(String propertyName, String label, UifConstants.ControlType controlType, 513 int size, int maxLength, int minLength) { 514 InputField field = (InputField) getNewComponentInstance(INPUT_FIELD); 515 516 field.setPropertyName(propertyName); 517 field.setLabel(label); 518 519 Control control = getControl(controlType); 520 if (control instanceof SizedControl) { 521 ((SizedControl) control).setSize(size); 522 } else { 523 throw new RuntimeException("Control does not support the size property"); 524 } 525 526 field.setMaxLength(maxLength); 527 field.setMinLength(minLength); 528 529 return field; 530 } 531 532 /** 533 * Builds a new <code>InputField</code> from the properties set on the 534 * given <code>RemotableAttributeField</code> 535 * 536 * <p> 537 * Note the returned InputField will not be initialized yet. Its state will be that of the initial 538 * object returned from the UIF dictionary with the properties set from the remotable attribute field, thus it 539 * is really just a more configuration complete field 540 * </p> 541 * 542 * @return AttributeField instance built from remotable field 543 */ 544 public static InputField translateRemotableField(RemotableAttributeField remotableField) { 545 InputField inputField = getInputField(); 546 547 inputField.setPropertyName(remotableField.getName()); 548 inputField.setShortLabel(remotableField.getShortLabel()); 549 inputField.setLabel(remotableField.getLongLabel()); 550 inputField.setConstraintText(remotableField.getConstraintText()); 551 inputField.setUppercaseValue(remotableField.isForceUpperCase()); 552 inputField.setMinLength(remotableField.getMinLength()); 553 inputField.setMaxLength(remotableField.getMaxLength()); 554 555 // why are exclusive min and max strings? 556 if (remotableField.getMinValue() != null) { 557 inputField.setExclusiveMin(remotableField.getMinValue().toString()); 558 } 559 if (remotableField.getMaxValue() != null) { 560 inputField.setInclusiveMax(remotableField.getMaxValue().toString()); 561 } 562 inputField.setRequired(remotableField.isRequired()); 563 564 if ((remotableField.getDefaultValues() != null) && !remotableField.getDefaultValues().isEmpty()) { 565 inputField.setDefaultValue(remotableField.getDefaultValues().iterator().next()); 566 } 567 568 if (StringUtils.isNotBlank(remotableField.getRegexConstraint())) { 569 ValidCharactersConstraint constraint = new ValidCharactersConstraint(); 570 constraint.setValue(remotableField.getRegexConstraint()); 571 inputField.setValidCharactersConstraint(constraint); 572 // TODO: how to deal with remotable field regexContraintMsg? 573 } 574 575 RemotableDatepicker remotableDatepicker = null; 576 RemotableTextExpand remotableTextExpand = null; 577 RemotableQuickFinder remotableQuickFinder = null; 578 for (RemotableAbstractWidget remoteWidget : remotableField.getWidgets()) { 579 if (remoteWidget instanceof RemotableDatepicker) { 580 remotableDatepicker = (RemotableDatepicker) remoteWidget; 581 } else if (remoteWidget instanceof RemotableTextExpand) { 582 remotableTextExpand = (RemotableTextExpand) remoteWidget; 583 } else if (remoteWidget instanceof RemotableQuickFinder) { 584 remotableQuickFinder = (RemotableQuickFinder) remoteWidget; 585 } 586 } 587 588 if (remotableQuickFinder != null) { 589 inputField.getQuickfinder().setBaseLookupUrl(remotableQuickFinder.getBaseLookupUrl()); 590 inputField.getQuickfinder().setDataObjectClassName(remotableQuickFinder.getDataObjectClass()); 591 inputField.getQuickfinder().setLookupParameters(remotableQuickFinder.getLookupParameters()); 592 inputField.getQuickfinder().setFieldConversions(remotableQuickFinder.getFieldConversions()); 593 } 594 595 if (remotableField.getControl() != null) { 596 Control control = null; 597 598 RemotableControlContract remotableControl = remotableField.getControl(); 599 if (remotableControl instanceof RemotableHiddenInput) { 600 control = getHiddenControl(); 601 } else if (remotableControl instanceof RemotableRadioButtonGroup) { 602 RemotableRadioButtonGroup remotableRadioButtonGroup = (RemotableRadioButtonGroup) remotableControl; 603 control = getRadioGroupControl(); 604 ((RadioGroupControl) control).setOptions(buildKeyValuePairs(remotableRadioButtonGroup.getKeyLabels())); 605 } else if (remotableControl instanceof RemotableSelect) { 606 RemotableSelect remotableSelect = (RemotableSelect) remotableControl; 607 control = getSelectControl(); 608 609 Map<String, String> keyLabels = new HashMap<String, String>(); 610 if ((remotableSelect.getGroups() != null) && (!remotableSelect.getGroups().isEmpty())) { 611 for (RemotableSelectGroup remotableSelectGroup : remotableSelect.getGroups()) { 612 keyLabels.putAll(remotableSelectGroup.getKeyLabels()); 613 } 614 } else { 615 keyLabels = remotableSelect.getKeyLabels(); 616 } 617 618 ((SelectControl) control).setOptions(buildKeyValuePairs(keyLabels)); 619 if (remotableSelect.getSize() != null) { 620 ((SelectControl) control).setSize(remotableSelect.getSize()); 621 } 622 ((SelectControl) control).setMultiple(remotableSelect.isMultiple()); 623 } else if (remotableControl instanceof RemotableCheckboxGroup) { 624 RemotableCheckboxGroup remotableCheckboxGroup = (RemotableCheckboxGroup) remotableControl; 625 control = getCheckboxGroupControl(); 626 ((CheckboxGroupControl) control).setOptions(buildKeyValuePairs(remotableCheckboxGroup.getKeyLabels())); 627 } else if (remotableControl instanceof RemotableCheckbox) { 628 control = getCheckboxControl(); 629 } else if (remotableControl instanceof RemotableTextarea) { 630 RemotableTextarea remotableTextarea = (RemotableTextarea) remotableControl; 631 control = getTextAreaControl(); 632 633 if (remotableTextExpand != null) { 634 ((TextAreaControl) control).setTextExpand(true); 635 } 636 ((TextAreaControl) control).setRows(remotableTextarea.getRows()); 637 ((TextAreaControl) control).setCols(remotableTextarea.getCols()); 638 ((TextAreaControl) control).setWatermarkText(remotableTextarea.getWatermark()); 639 640 } else if (remotableControl instanceof RemotableTextInput) { 641 RemotableTextInput remotableTextInput = (RemotableTextInput) remotableControl; 642 643 if (remotableDatepicker != null) { 644 control = getDateControl(); 645 } else { 646 control = getTextControl(); 647 } 648 649 if (remotableTextExpand != null) { 650 ((TextAreaControl) control).setTextExpand(true); 651 } 652 ((TextControl) control).setSize(remotableTextInput.getSize()); 653 ((TextControl) control).setWatermarkText(remotableTextInput.getWatermark()); 654 } 655 656 inputField.setControl(control); 657 } 658 659 return inputField; 660 } 661 662 /** 663 * For each remotable field in the given list creates a new {@link org.kuali.rice.krad.uif.field.InputField} 664 * instance and sets the 665 * corresponding properties from the remotable instance 666 * 667 * @param remotableFields - list of remotable fields to translate 668 * @return List<AttributeField> list of attribute fields built from the remotable field properties 669 */ 670 public static List<InputField> translateRemotableFields(List<RemotableAttributeField> remotableFields) { 671 List<InputField> inputFields = new ArrayList<InputField>(); 672 673 for (RemotableAttributeField remotableField : remotableFields) { 674 inputFields.add(translateRemotableField(remotableField)); 675 } 676 677 return inputFields; 678 } 679 680 /** 681 * For each option in the given list, create a new {@link org.kuali.rice.core.api.util.KeyValue} instance 682 * 683 * @param optionsMap - list of options 684 * @return List<KeyValue> list of key values built from the list of options 685 */ 686 protected static List<KeyValue> buildKeyValuePairs(Map<String, String> optionsMap) { 687 List<KeyValue> options = new ArrayList<KeyValue>(); 688 689 for (Map.Entry<String, String> optionEntry : optionsMap.entrySet()) { 690 KeyValue keyValue = new ConcreteKeyValue(optionEntry.getKey(), optionEntry.getValue()); 691 options.add(keyValue); 692 } 693 694 return options; 695 } 696 697 /** 698 * Gets the control 699 * 700 * @param controlType 701 * @return Control the control based on the control type 702 */ 703 protected static Control getControl(UifConstants.ControlType controlType) { 704 Control control = null; 705 switch (controlType) { 706 case CHECKBOX: 707 control = getCheckboxControl(); 708 case CHECKBOXGROUP: 709 control = getCheckboxGroupControl(); 710 case FILE: 711 control = getFileControl(); 712 case GROUP: 713 control = getGroupControl(); 714 case HIDDEN: 715 control = getHiddenControl(); 716 case RADIOGROUP: 717 control = getRadioGroupControl(); 718 case SELECT: 719 control = getSelectControl(); 720 case TEXTAREA: 721 control = getTextAreaControl(); 722 case TEXT: 723 control = getTextControl(); 724 case USER: 725 control = getUserControl(); 726 } 727 728 return control; 729 } 730 731 /** 732 * Gets the errors field 733 * 734 * @return ValidationMessages errors field 735 */ 736 public static ValidationMessages getErrorsField() { 737 return (ValidationMessages) getNewComponentInstance(ERRORS_FIELD); 738 } 739 740 /** 741 * Gets the action 742 * 743 * @return Action action 744 */ 745 public static Action getAction() { 746 return (Action) getNewComponentInstance(ACTION); 747 } 748 749 /** 750 * Gets the action link 751 * 752 * @return Action action link 753 */ 754 public static Action getActionLink() { 755 return (Action) getNewComponentInstance(ACTION_LINK); 756 } 757 758 /** 759 * Gets the link field 760 * 761 * @return LinkField link field 762 */ 763 public static LinkField getLinkField() { 764 return (LinkField) getNewComponentInstance(LINK_FIELD); 765 } 766 767 /** 768 * Gets the iframe 769 * 770 * @return Iframe iframe 771 */ 772 public static Iframe getIframe() { 773 return (Iframe) getNewComponentInstance(IFRAME); 774 } 775 776 /** 777 * Gets the image field 778 * 779 * @return ImageField image field 780 */ 781 public static ImageField getImageField() { 782 return (ImageField) getNewComponentInstance(IMAGE_FIELD); 783 } 784 785 /** 786 * Gets the image component 787 * 788 * @return ImageField image field 789 */ 790 public static Image getImage() { 791 return (Image) getNewComponentInstance(IMAGE); 792 } 793 794 /** 795 * Gets the space field 796 * 797 * @return SpaceField space field 798 */ 799 public static SpaceField getSpaceField() { 800 return (SpaceField) getNewComponentInstance(SPACE_FIELD); 801 } 802 803 /** 804 * Gets the generic field 805 * 806 * @return GenericField generic field 807 */ 808 public static GenericField getGenericField() { 809 return (GenericField) getNewComponentInstance(GENERIC_FIELD); 810 } 811 812 /** 813 * Gets the label 814 * 815 * @return Label label 816 */ 817 public static Label getLabel() { 818 return (Label) getNewComponentInstance(LABEL); 819 } 820 821 /** 822 * Gets the message 823 * 824 * @return Message message 825 */ 826 public static Message getMessage() { 827 return (Message) getNewComponentInstance(MESSAGE); 828 } 829 830 /** 831 * Gets the message field 832 * 833 * @return MessageField message field 834 */ 835 public static MessageField getMessageField() { 836 return (MessageField) getNewComponentInstance(MESSAGE_FIELD); 837 } 838 839 /** 840 * Gets the field group 841 * 842 * @return FieldGroup field group 843 */ 844 public static FieldGroup getFieldGroup() { 845 return (FieldGroup) getNewComponentInstance(FIELD_GROUP); 846 } 847 848 /** 849 * Gets the horizontal field group 850 * 851 * @return FieldGroup horizontal field group 852 */ 853 public static FieldGroup getHorizontalFieldGroup() { 854 return (FieldGroup) getNewComponentInstance(HORIZONTAL_FIELD_GROUP); 855 } 856 857 /** 858 * Gets the group 859 * 860 * @return Group group 861 */ 862 public static Group getGroup() { 863 return (Group) getNewComponentInstance(GROUP); 864 } 865 866 /** 867 * Gets the page group 868 * 869 * @return PageGroup page group 870 */ 871 public static PageGroup getPageGroup() { 872 return (PageGroup) getNewComponentInstance(PAGE_GROUP); 873 } 874 875 /** 876 * Gets the group grid layout 877 * 878 * @return Group group grid layout 879 */ 880 public static Group getGroupGridLayout() { 881 return (Group) getNewComponentInstance(GROUP_GRID_LAYOUT); 882 } 883 884 /** 885 * Gets the group body only 886 * 887 * @return Group group body only 888 */ 889 public static Group getGroupBodyOnly() { 890 return (Group) getNewComponentInstance(GROUP_BODY_ONLY); 891 } 892 893 /** 894 * Gets the group grid body only 895 * 896 * @return Group group grid body only 897 */ 898 public static Group getGroupGridBodyOnly() { 899 return (Group) getNewComponentInstance(GROUP_GRID_BODY_ONLY); 900 } 901 902 /** 903 * Gets the tab group 904 * 905 * @return TabGroup tab group 906 */ 907 public static TabGroup getTabGroup() { 908 return (TabGroup) getNewComponentInstance(TAB_GROUP); 909 } 910 911 /** 912 * Gets the navigation group 913 * 914 * @return NavigationGroup navigation group 915 */ 916 public static NavigationGroup getNavigationGroup() { 917 return (NavigationGroup) getNewComponentInstance(NAVIGATION_GROUP); 918 } 919 920 /** 921 * Gets the tree group 922 * 923 * @return TreeGroup tree group 924 */ 925 public static TreeGroup getTreeGroup() { 926 return (TreeGroup) getNewComponentInstance(TREE_GROUP); 927 } 928 929 /** 930 * Gets the link group 931 * 932 * @return LinkGroup link group 933 */ 934 public static LinkGroup getLinkGroup() { 935 return (LinkGroup) getNewComponentInstance(LINK_GROUP); 936 } 937 938 /** 939 * Gets the collection group 940 * 941 * @return CollectionGroup collection group 942 */ 943 public static CollectionGroup getCollectionGroup() { 944 return (CollectionGroup) getNewComponentInstance(COLLECTION_GROUP); 945 } 946 947 /** 948 * Gets the collection group table layout 949 * 950 * @return CollectionGroup collection group table layout 951 */ 952 public static CollectionGroup getCollectionGroupTableLayout() { 953 return (CollectionGroup) getNewComponentInstance(COLLECTION_GROUP_TABLE_LAYOUT); 954 } 955 956 /** 957 * Gets the list group 958 * 959 * @return CollectionGroup list group 960 */ 961 public static CollectionGroup getListGroup() { 962 return (CollectionGroup) getNewComponentInstance(LIST_GROUP); 963 } 964 965 /** 966 * Gets the header 967 * 968 * @return Header header 969 */ 970 public static Header getHeader() { 971 return (Header) getNewComponentInstance(HEADER); 972 } 973 974 /** 975 * Gets the footer 976 * 977 * @return Group footer 978 */ 979 public static Group getFooter() { 980 return (Group) getNewComponentInstance(FOOTER); 981 } 982 983 /** 984 * Gets the footer save/close/cancel 985 * 986 * @return Group footer save/close/cancel 987 */ 988 public static Group getFooterSaveCloseCancel() { 989 return (Group) getNewComponentInstance(FOOTER_SAVECLOSECANCEL); 990 } 991 992 /** 993 * Gets the default action component configured for help 994 * 995 * @return Action for help display 996 */ 997 public static Action getHelpAction() { 998 return (Action) getNewComponentInstance(HELP_ACTION); 999 } 1000 1001 /** 1002 * Gets the default constraint message configuration 1003 * 1004 * @return Message component for constraint messages 1005 */ 1006 public static Message getConstraintMessage() { 1007 return (Message) getNewComponentInstance(CONSTRAINT_MESSAGE); 1008 } 1009 1010 /** 1011 * Gets the default instructional message configuration 1012 * 1013 * @return Message component for instructional messages 1014 */ 1015 public static Message getInstructionalMessage() { 1016 return (Message) getNewComponentInstance(INSTRUCTIONAL_MESSAGE); 1017 } 1018 1019 /** 1020 * Gets the default image caption header configuration 1021 * 1022 * @return Header component for image caption headers 1023 */ 1024 public static Header getImageCaptionHeader() { 1025 return (Header) getNewComponentInstance(IMAGE_CAPTION_HEADER); 1026 } 1027 1028 /** 1029 * Gets the default image cutline message configuration 1030 * 1031 * @return Message component for image cutlines messages 1032 */ 1033 public static Message getImageCutlineMessage() { 1034 return (Message) getNewComponentInstance(IMAGE_CUTLINE_MESSAGE); 1035 } 1036 }