1 /**
2 * Copyright 2005-2011 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.uif.component;
17
18 import org.kuali.rice.krad.uif.modifier.ComponentModifier;
19 import org.kuali.rice.krad.uif.service.ViewHelperService;
20 import org.kuali.rice.krad.uif.view.View;
21
22 import java.io.Serializable;
23 import java.util.List;
24 import java.util.Map;
25
26 /**
27 * All classes of the UIF that are used as a rendering element implement the
28 * component interface. This interface defines basic properties and methods that
29 * all such classes much implement. All components within the framework have the
30 * following structure:
31 * <ul>
32 * <li>Dictionary Configuration/Composition</li>
33 * <li>Java Class (the Component implementation</li>
34 * <li>>JSP Template Renderer</li>
35 * </ul>
36 *
37 * There are three basic types of components:
38 * <ul>
39 * <li>Container Components: <code>View</code>, <code>Group</code></li>
40 * <li>Field Components: <code>Field</code></li>
41 * <li>Widget Components: <code>Widget</code></li>
42 * </ul>
43 *
44 * @author Kuali Rice Team (rice.collab@kuali.org)
45 * @see org.kuali.rice.krad.uif.container.Container
46 * @see org.kuali.rice.krad.uif.field.Field
47 * @see org.kuali.rice.krad.uif.widget.Widget
48 */
49 public interface Component extends Configurable, Serializable, Ordered, ScriptEventSupport {
50
51 /**
52 * The unique id (within a given tree) for the component
53 *
54 * <p>
55 * The id will be used by renderers to set the HTML element id. This gives a
56 * way to find various elements for scripting. If the id is not given, a
57 * default will be generated by the framework
58 * </p>
59 *
60 * @return String id
61 */
62 public String getId();
63
64 /**
65 * Sets the unique id (within a given tree) for the component
66 *
67 * @param id - string to set as the component id
68 */
69 public void setId(String id);
70
71 /**
72 * Holds the id for the component that can be used to request new instances of that component from the
73 * {@link org.kuali.rice.krad.uif.util.ComponentFactory}
74 *
75 * <p>
76 * During component refreshes the component is reinitialized and the lifecycle is performed again to
77 * reflect the component state based on the latest updates (data, other component state). Since the lifecycle
78 * is only performed on the component, a new instance with configured initial state needs to be retrieved. Some
79 * component instances, such as those that are nested or created in code, cannot be obtained from the spring
80 * factory. For those the initial state is captured during the perform initialize phase and the factory id
81 * generated for referencing retrieving that configuration during a refresh
82 * </p>
83 *
84 * @return String bean id for component
85 */
86 public String getFactoryId();
87
88 /**
89 * Sets the factory id that backs the component instance
90 *
91 * @param factoryId
92 */
93 public void setFactoryId(String factoryId);
94
95 /**
96 * The name for the component type
97 *
98 * <p>
99 * This is used within the rendering layer to pass the component instance
100 * into the template. The component instance is exported under the name
101 * given by this method.
102 * </p>
103 *
104 * @return String type name
105 */
106 public String getComponentTypeName();
107
108 /**
109 * The path to the JSP file that should be called to render the component
110 *
111 * <p>
112 * The path should be relative to the web root. An attribute will be
113 * available to the component to use under the name given by the method
114 * <code>getComponentTypeName</code>. Based on the component type,
115 * additional attributes could be available for use. See the component
116 * documentation for more information on such attributes.
117 * </p>
118 *
119 * <p>
120 * e.g. '/krad/WEB-INF/jsp/tiles/component.jsp'
121 * </p>
122 *
123 * @return String representing the template path
124 */
125 public String getTemplate();
126
127 /**
128 * Setter for the components template
129 *
130 * @param template
131 */
132 public void setTemplate(String template);
133
134 /**
135 * A title for the component. Depending on the component can be used in
136 * various ways. For example with a Container component the title is used to
137 * set the header text. For components like controls other other components
138 * that render an HTML element it is used to set the HTML title attribute
139 *
140 * @return String title for component
141 */
142 public String getTitle();
143
144 /**
145 * Setter for the components title
146 *
147 * @param title
148 */
149 public void setTitle(String title);
150
151 /**
152 * Should be called to initialize the component
153 *
154 * <p>
155 * Where components can set defaults and setup other necessary state. The
156 * initialize method should only be called once per component lifecycle and
157 * is invoked within the initialize phase of the view lifecylce.
158 * </p>
159 *
160 * @param view - view instance in which the component belongs
161 * @param model - object instance containing the view data
162 * @see ViewHelperService#initializeComponent
163 */
164 public void performInitialization(View view, Object model);
165
166 /**
167 * Called after the initialize phase to perform conditional logic based on
168 * the model data
169 *
170 * <p>
171 * Where components can perform conditional logic such as dynamically
172 * generating new fields or setting field state based on the given data
173 * </p>
174 *
175 * @param view - view instance to which the component belongs
176 * @param model - Top level object containing the data (could be the form or a
177 * top level business object, dto)
178 */
179 public void performApplyModel(View view, Object model, Component parent);
180
181 /**
182 * The last phase before the view is rendered. Here final preparations can
183 * be made based on the updated view state
184 *
185 * @param view - view instance that should be finalized for rendering
186 * @param model - top level object containing the data
187 * @param parent - parent component
188 */
189 public void performFinalize(View view, Object model, Component parent);
190
191 /**
192 * List of components that are contained within the component and should be sent through
193 * the lifecycle
194 *
195 * <p>
196 * Used by <code>ViewHelperService</code> for the various lifecycle
197 * callbacks
198 * </p>
199 *
200 * @return List<Component> child components
201 */
202 public List<Component> getComponentsForLifecycle();
203
204 /**
205 * List of components that are maintained by the component as prototypes for creating other component instances
206 *
207 * <p>
208 * Prototypes are held for configuring how a component should be created during the lifecycle. An example of this
209 * are the fields in a collection group that are created for each collection record. They only participate in the
210 * initialize phase.
211 * </p>
212 *
213 * @return List<Component> child component prototypes
214 */
215 public List<Component> getComponentPrototypes();
216
217 /**
218 * List of components that are contained within the List of <code>PropertyReplacer</code> in component
219 *
220 * <p>
221 * Used to get all the nested components in the property replacer's
222 * </p>
223 *
224 * @return List<Component> <code>PropertyReplacer</code> child components
225 */
226 public List<Component> getPropertyReplacerComponents();
227
228 /**
229 * <code>ComponentModifier</code> instances that should be invoked to
230 * initialize the component
231 *
232 * <p>
233 * These provide dynamic initialization behavior for the component and are
234 * configured through the components definition. Each initializer will get
235 * invoked by the initialize method.
236 * </p>
237 *
238 * @return List of component modifiers
239 * @see ViewHelperService#initializeComponent
240 */
241 public List<ComponentModifier> getComponentModifiers();
242
243 /**
244 * Setter for the components List of <code>ComponentModifier</code>
245 * instances
246 *
247 * @param componentModifiers
248 */
249 public void setComponentModifiers(List<ComponentModifier> componentModifiers);
250
251 /**
252 * Indicates whether the component should be rendered in the UI
253 *
254 * <p>
255 * If set to false, the corresponding component template will not be invoked
256 * (therefore nothing will be rendered to the UI).
257 * </p>
258 *
259 * @return boolean true if the component should be rendered, false if it
260 * should not be
261 */
262 public boolean isRender();
263
264 /**
265 * Setter for the components render indicator
266 *
267 * @param render
268 */
269 public void setRender(boolean render);
270
271 /**
272 * Indicates whether the component should be hidden in the UI
273 *
274 * <p>
275 * How the hidden data is maintained depends on the views persistence mode.
276 * If the mode is request, the corresponding data will be rendered to the UI
277 * but not visible. If the mode is session, the data will not be rendered to
278 * the UI but maintained server side.
279 * </p>
280 *
281 * <p>
282 * For a <code>Container</code> component, the hidden setting will apply to
283 * all contained components (making a section hidden makes all fields within
284 * the section hidden)
285 * </p>
286 *
287 * @return boolean true if the component should be hidden, false if it
288 * should be visible
289 */
290 public boolean isHidden();
291
292 /**
293 * Setter for the hidden indicator
294 *
295 * @param hidden
296 */
297 public void setHidden(boolean hidden);
298
299 /**
300 * Indicates whether the component can be edited
301 *
302 * <p>
303 * When readOnly the controls and widgets of <code>Field</code> components
304 * will not be rendered. If the Field has an underlying value it will be
305 * displayed readOnly to the user.
306 * </p>
307 *
308 * <p>
309 * For a <code>Container</code> component, the readOnly setting will apply
310 * to all contained components (making a section readOnly makes all fields
311 * within the section readOnly)
312 * </p>
313 * </p>
314 *
315 * @return boolean true if the component should be readOnly, false if is
316 * allows editing
317 */
318 public boolean isReadOnly();
319
320 /**
321 * Setter for the read only indicator
322 *
323 * @param readOnly
324 */
325 public void setReadOnly(boolean readOnly);
326
327 /**
328 * Indicates whether the component is required
329 *
330 * <p>
331 * At the general component level required means there is some action the
332 * user needs to take within the component. For example, within a section it
333 * might mean the fields within the section should be completed. At a field
334 * level, it means the field should be completed. This provides the ability
335 * for the renderers to indicate the required action.
336 * </p>
337 *
338 * @return boolean true if the component is required, false if it is not
339 * required
340 */
341 public Boolean getRequired();
342
343 /**
344 * Setter for the required indicator
345 *
346 * @param required
347 */
348 public void setRequired(Boolean required);
349
350 /**
351 * CSS style string to be applied to the component
352 *
353 * <p>
354 * Any style override or additions can be specified with this attribute.
355 * This is used by the renderer to set the style attribute on the
356 * corresponding element.
357 * </p>
358 *
359 * <p>
360 * e.g. 'color: #000000;text-decoration: underline;'
361 * </p>
362 *
363 * @return String css style string
364 */
365 public String getStyle();
366
367 /**
368 * Setter for the components style
369 *
370 * @param style
371 */
372 public void setStyle(String style);
373
374 /**
375 * CSS style class(s) to be applied to the component
376 *
377 * <p>
378 * Declares style classes for the component. Multiple classes are specified
379 * with a space delimiter. This is used by the renderer to set the class
380 * attribute on the corresponding element. The class(s) declared must be
381 * available in the common style sheets or the style sheets specified for
382 * the view
383 * </p>
384 *
385 * <p>
386 * e.g. 'header left'
387 * </p>
388 *
389 * @return List<String> css style classes to apply
390 */
391 public List<String> getStyleClasses();
392
393 /**
394 * Setter for the components style classes
395 *
396 * @param styleClass
397 */
398 public void setStyleClasses(List<String> styleClasses);
399
400 /**
401 * Adds a single style to the list of styles on this component
402 *
403 * @param style
404 */
405 public void addStyleClass(String styleClass);
406
407 /**
408 * TODO: javadoc
409 *
410 * @param itemStyle
411 */
412 public void appendToStyle(String itemStyle);
413
414 /**
415 * Number of places the component should take up horizontally in the
416 * container
417 *
418 * <p>
419 * All components belong to a <code>Container</code> and are placed using a
420 * <code>LayoutManager</code>. This property specifies how many places
421 * horizontally the component should take up within the container. This is
422 * only applicable for table based layout managers. Default is 1
423 * </p>
424 *
425 * TODO: this should not be on component interface since it only applies if
426 * the layout manager supports it, need some sort of layoutOptions map for
427 * field level options that depend on the manager
428 *
429 * @return int number of columns to span
430 */
431 public int getColSpan();
432
433 /**
434 * Setter for the components column span
435 *
436 * @param colSpan
437 */
438 public void setColSpan(int colSpan);
439
440 /**
441 * Number of places the component should take up vertically in the container
442 *
443 * <p>
444 * All components belong to a <code>Container</code> and are placed using a
445 * <code>LayoutManager</code>. This property specifies how many places
446 * vertically the component should take up within the container. This is
447 * only applicable for table based layout managers. Default is 1
448 * </p>
449 *
450 * TODO: this should not be on component interface since it only applies if
451 * the layout manager supports it, need some sort of layoutOptions map for
452 * field level options that depend on the manager
453 *
454 * @return int number of rows to span
455 */
456 public int getRowSpan();
457
458 /**
459 * Setter for the component row span
460 *
461 * @param rowSpan
462 */
463 public void setRowSpan(int rowSpan);
464
465 /**
466 * Context map for the component
467 *
468 * <p>
469 * Any el statements configured for the components properties (e.g.
470 * title="@{foo.property}") are evaluated using the el context map. This map
471 * will get populated with default objects like the model, view, and request
472 * from the <code>ViewHelperService</code>. Other components can push
473 * further objects into the context so that they are available for use with
474 * that component. For example, <code>Field</code> instances that are part
475 * of a collection line as receive the current line instance
476 * </p>
477 *
478 * <p>
479 * Context map also provides objects to methods that are invoked for
480 * <code>GeneratedField</code> instances
481 * </p>
482 *
483 * <p>
484 * The Map key gives the name of the variable that can be used within
485 * expressions, and the Map value gives the object instance for which
486 * expressions containing the variable should evaluate against
487 * </p>
488 *
489 * <p>
490 * NOTE: Calling getContext().putAll() will skip updating any configured property replacers for the
491 * component. Instead you should call #pushAllToContext
492 * </p>
493 *
494 * @return Map<String, Object> context
495 */
496 public Map<String, Object> getContext();
497
498 /**
499 * Setter for the context Map
500 *
501 * @param context
502 */
503 public void setContext(Map<String, Object> context);
504
505 /**
506 * Places the given object into the context Map for the component with the
507 * given name
508 *
509 * <p>
510 * Note this also will push context to property replacers configured on the component.
511 * To place multiple objects in the context, you should use #pushAllToContext since that
512 * will call this method for each and update property replacers. Using #getContext().putAll()
513 * will bypass property replacers.
514 * </p>
515 *
516 * @param objectName - name the object should be exposed under in the context map
517 * @param object - object instance to place into context
518 */
519 public void pushObjectToContext(String objectName, Object object);
520
521 /**
522 * Places each entry of the given Map into the context for the component
523 *
524 * <p>
525 * Note this will call #pushObjectToContext for each entry which will update any configured property
526 * replacers as well. This should be used in place of getContext().putAll()
527 * </p>
528 *
529 * @param objects - Map<String, Object> objects to add to context, where the entry key will be the context key
530 * and the entry value will be the context value
531 */
532 public void pushAllToContext(Map<String, Object> objects);
533
534 /**
535 * List of <code>PropertyReplacer</code> instances that will be evaluated
536 * during the view lifecycle to conditionally set properties on the
537 * <code>Component</code> based on expression evaluations
538 *
539 * @return List<PropertyReplacer> replacers to evaluate
540 */
541 public List<PropertyReplacer> getPropertyReplacers();
542
543 /**
544 * Setter for the components property substitutions
545 *
546 * @param propertyReplacers
547 */
548 public void setPropertyReplacers(List<PropertyReplacer> propertyReplacers);
549
550 /**
551 * Options that are passed through to the Component renderer. The Map key is
552 * the option name, with the Map value as the option value. See
553 * documentation on the particular widget render for available options.
554 *
555 * @return Map<String, String> options
556 */
557 public Map<String, String> getComponentOptions();
558
559 /**
560 * Setter for the widget's options
561 *
562 * @param widgetOptions
563 */
564 public void setComponentOptions(Map<String, String> componentOptions);
565
566 /**
567 * Options that are passed through to the Component renderer. See
568 * documentation on the particular widget render for available options.
569 *
570 * @return String options
571 */
572 public String getComponentOptionsJSString();
573
574 /**
575 * Setter for the widget's options
576 *
577 * @param widgetOptions
578 */
579 public void setComponentOptionsJSString(String componentOptions);
580
581 /**
582 * Can be used to order a component within a List of other components, lower
583 * numbers are placed higher up in the list, while higher numbers are placed
584 * lower in the list
585 *
586 * @return int ordering number
587 * @see org.springframework.core.Ordered#getOrder()
588 */
589 public int getOrder();
590
591 /**
592 * Setter for the component's order
593 *
594 * @param order
595 */
596 public void setOrder(int order);
597
598 /**
599 * Name of the method that should be invoked for finalizing the component
600 * configuration (full method name, without parameters or return type)
601 *
602 * <p>
603 * Note the method can also be set with the finalizeMethodInvoker
604 * targetMethod property. If the method is on the configured
605 * <code>ViewHelperService</code>, only this property needs to be configured
606 * </p>
607 *
608 * <p>
609 * The model backing the view will be passed as the first argument method and then
610 * the <code>Component</code> instance as the second argument. If any additional method
611 * arguments are declared with the finalizeMethodAdditionalArguments, they will then
612 * be passed in the order declared in the list
613 * </p>
614 *
615 * <p>
616 * If the component is selfRendered, the finalize method can return a string which
617 * will be set as the component's renderOutput. The selfRendered indicator will also
618 * be set to true on the component.
619 * </p>
620 *
621 * @return String method name
622 */
623 public String getFinalizeMethodToCall();
624
625 /**
626 * List of Object instances that should be passed as arguments to the finalize method
627 *
628 * <p>
629 * These arguments are passed to the finalize method after the standard model and component
630 * arguments. They are passed in the order declared in the list
631 * </p>
632 *
633 * @return List<Object> additional method arguments
634 */
635 public List<Object> getFinalizeMethodAdditionalArguments();
636
637 /**
638 * <code>MethodInvokerConfig</code> instance for the method that should be invoked
639 * for finalizing the component configuration
640 *
641 * <p>
642 * MethodInvoker can be configured to specify the class or object the method
643 * should be called on. For static method invocations, the targetClass
644 * property can be configured. For object invocations, that targetObject
645 * property can be configured
646 * </p>
647 *
648 * <p>
649 * If the component is selfRendered, the finalize method can return a string which
650 * will be set as the component's renderOutput. The selfRendered indicator will also
651 * be set to true on the component.
652 * </p>
653 *
654 * @return MethodInvokerConfig instance
655 */
656 public MethodInvokerConfig getFinalizeMethodInvoker();
657
658 /**
659 * Indicates whether the component contains its own render output (through
660 * the renderOutput property)
661 *
662 * <p>
663 * If self rendered is true, the corresponding template for the component
664 * will not be invoked and the renderOutput String will be written to the
665 * response as is.
666 * </p>
667 *
668 * @return boolean true if component is self rendered, false if not (renders
669 * through template)
670 */
671 public boolean isSelfRendered();
672
673 /**
674 * Setter for the self render indicator
675 *
676 * @param selfRendered
677 */
678 public void setSelfRendered(boolean selfRendered);
679
680 /**
681 * Rendering output for the component that will be sent as part of the
682 * response (can contain static text and HTML)
683 *
684 * @return String render output
685 */
686 public String getRenderOutput();
687
688 /**
689 * Setter for the component's render output
690 *
691 * @param renderOutput
692 */
693 public void setRenderOutput(String renderOutput);
694
695 /**
696 * @return the progressiveRender
697 */
698 public String getProgressiveRender();
699
700 /**
701 * @param progressiveRender the progressiveRender to set
702 */
703 public void setProgressiveRender(String progressiveRender);
704
705 /**
706 * @return the conditionalRefresh
707 */
708 public String getConditionalRefresh();
709
710 /**
711 * @param conditionalRefresh the conditionalRefresh to set
712 */
713 public void setConditionalRefresh(String conditionalRefresh);
714
715 /**
716 * @return the progressiveDisclosureControlNames
717 */
718 public List<String> getProgressiveDisclosureControlNames();
719
720 /**
721 * @return the progressiveDisclosureConditionJs
722 */
723 public String getProgressiveDisclosureConditionJs();
724
725 /**
726 * @return the conditionalRefreshConditionJs
727 */
728 public String getConditionalRefreshConditionJs();
729
730 /**
731 * @return the conditionalRefreshControlNames
732 */
733 public List<String> getConditionalRefreshControlNames();
734
735 /**
736 * @return the progressiveRenderViaAJAX
737 */
738 public boolean isProgressiveRenderViaAJAX();
739
740 /**
741 * @param progressiveRenderViaAJAX the progressiveRenderViaAJAX to set
742 */
743 public void setProgressiveRenderViaAJAX(boolean progressiveRenderViaAJAX);
744
745 /**
746 * If true, when the progressiveRender condition is satisfied, the component
747 * will always be retrieved from the server and shown(as opposed to being
748 * stored on the client, but hidden, after the first retrieval as is the
749 * case with the progressiveRenderViaAJAX option). <b>By default, this is
750 * false, so components with progressive render capabilities will always be
751 * already within the client html and toggled to be hidden or visible.</b>
752 *
753 * @return the progressiveRenderAndRefresh
754 */
755 public boolean isProgressiveRenderAndRefresh();
756
757 /**
758 * @param progressiveRenderAndRefresh the progressiveRenderAndRefresh to set
759 */
760 public void setProgressiveRenderAndRefresh(boolean progressiveRenderAndRefresh);
761
762 /**
763 * Specifies a property by name that when it value changes will
764 * automatically perform a refresh on this component. This can be a comma
765 * separated list of multiple properties that require this component to be
766 * refreshed when any of them change. <Br>DO NOT use with progressiveRender
767 * unless it is know that progressiveRender condition will always be
768 * satisfied before one of these fields can be changed.
769 *
770 * @return the refreshWhenChanged
771 */
772 public String getRefreshWhenChanged();
773
774 /**
775 * @param refreshWhenChanged the refreshWhenChanged to set
776 */
777 public void setRefreshWhenChanged(String refreshWhenChanged);
778
779 /**
780 * Indicates the component can be refreshed by an action
781 *
782 * <p>
783 * This is set by the framework for configured ajax action buttons, should not be set in
784 * configuration
785 * </p>
786 *
787 * @return boolean true if the component is refreshed by an action, false if not
788 */
789 public boolean isRefreshedByAction();
790
791 /**
792 * Setter for the refresjed by action indicator
793 *
794 * <p>
795 * This is set by the framework for configured ajax action buttons, should not be set in
796 * configuration
797 * </p>
798 *
799 * @param refreshedByAction
800 */
801 public void setRefreshedByAction(boolean refreshedByAction);
802
803 /**
804 * Indicates whether data contained within the component should be reset (set to default) when the
805 * component is refreshed
806 *
807 * @return boolean true if data should be refreshed, false if data should remain as is
808 */
809 public boolean isResetDataOnRefresh();
810
811 /**
812 * Setter for the reset data on refresh indicator
813 *
814 * @param resetDataOnRefresh
815 */
816 public void setResetDataOnRefresh(boolean resetDataOnRefresh);
817
818 /**
819 * Result of the conditionalRefresh expression, true if satisfied, otherwise false.
820 * Note: not currently used for any processing, required by the expression evaluator.
821 *
822 * @return the refresh
823 */
824 public boolean isRefresh();
825
826 /**
827 * @param refresh the refresh to set
828 */
829 public void setRefresh(boolean refresh);
830
831 /**
832 * Control names which will refresh this component when they are changed, added
833 * internally
834 *
835 * @return the refreshWhenChangedControlNames
836 */
837 public List<String> getRefreshWhenChangedControlNames();
838
839 }