1 /**
2 * Copyright 2005-2012 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 * Indicates whether the component should be stored with the session view regardless of configuration
697 *
698 * <p>
699 * By default the framework nulls out any components that do not have a refresh condition or are needed for
700 * collection processing. This can be a problem if custom application code is written to refresh a component
701 * without setting the corresponding component flag. In this case this property can be set to true to force the
702 * framework to keep the component in session. Defaults to false
703 * </p>
704 *
705 * @return boolean true if the component should be stored in session, false if not
706 */
707 public boolean isPersistInSession();
708
709 /**
710 * Setter for the indicator to force persistence of the component in session
711 *
712 * @param persistInSession
713 */
714 public void setPersistInSession(boolean persistInSession);
715
716 /**
717 * Security object that indicates what authorization (permissions) exist for the component
718 *
719 * @return ComponentSecurity instance
720 */
721 public ComponentSecurity getComponentSecurity();
722
723 /**
724 * Setter for the components security object
725 *
726 * @param componentSecurity
727 */
728 public void setComponentSecurity(ComponentSecurity componentSecurity);
729
730 /**
731 * @return the progressiveRender
732 */
733 public String getProgressiveRender();
734
735 /**
736 * @param progressiveRender the progressiveRender to set
737 */
738 public void setProgressiveRender(String progressiveRender);
739
740 /**
741 * @return the conditionalRefresh
742 */
743 public String getConditionalRefresh();
744
745 /**
746 * @param conditionalRefresh the conditionalRefresh to set
747 */
748 public void setConditionalRefresh(String conditionalRefresh);
749
750 /**
751 * @return the progressiveDisclosureControlNames
752 */
753 public List<String> getProgressiveDisclosureControlNames();
754
755 /**
756 * @return the progressiveDisclosureConditionJs
757 */
758 public String getProgressiveDisclosureConditionJs();
759
760 /**
761 * @return the conditionalRefreshConditionJs
762 */
763 public String getConditionalRefreshConditionJs();
764
765 /**
766 * @return the conditionalRefreshControlNames
767 */
768 public List<String> getConditionalRefreshControlNames();
769
770 /**
771 * @return the progressiveRenderViaAJAX
772 */
773 public boolean isProgressiveRenderViaAJAX();
774
775 /**
776 * @param progressiveRenderViaAJAX the progressiveRenderViaAJAX to set
777 */
778 public void setProgressiveRenderViaAJAX(boolean progressiveRenderViaAJAX);
779
780 /**
781 * If true, when the progressiveRender condition is satisfied, the component
782 * will always be retrieved from the server and shown(as opposed to being
783 * stored on the client, but hidden, after the first retrieval as is the
784 * case with the progressiveRenderViaAJAX option). <b>By default, this is
785 * false, so components with progressive render capabilities will always be
786 * already within the client html and toggled to be hidden or visible.</b>
787 *
788 * @return the progressiveRenderAndRefresh
789 */
790 public boolean isProgressiveRenderAndRefresh();
791
792 /**
793 * @param progressiveRenderAndRefresh the progressiveRenderAndRefresh to set
794 */
795 public void setProgressiveRenderAndRefresh(boolean progressiveRenderAndRefresh);
796
797 /**
798 * Specifies a property by name that when it value changes will
799 * automatically perform a refresh on this component. This can be a comma
800 * separated list of multiple properties that require this component to be
801 * refreshed when any of them change. <Br>DO NOT use with progressiveRender
802 * unless it is know that progressiveRender condition will always be
803 * satisfied before one of these fields can be changed.
804 *
805 * @return the refreshWhenChanged
806 */
807 public String getRefreshWhenChanged();
808
809 /**
810 * @param refreshWhenChanged the refreshWhenChanged to set
811 */
812 public void setRefreshWhenChanged(String refreshWhenChanged);
813
814 /**
815 * Indicates the component can be refreshed by an action
816 *
817 * <p>
818 * This is set by the framework for configured ajax action buttons, should not be set in
819 * configuration
820 * </p>
821 *
822 * @return boolean true if the component is refreshed by an action, false if not
823 */
824 public boolean isRefreshedByAction();
825
826 /**
827 * Setter for the refresjed by action indicator
828 *
829 * <p>
830 * This is set by the framework for configured ajax action buttons, should not be set in
831 * configuration
832 * </p>
833 *
834 * @param refreshedByAction
835 */
836 public void setRefreshedByAction(boolean refreshedByAction);
837
838 /**
839 * Indicates whether data contained within the component should be reset (set to default) when the
840 * component is refreshed
841 *
842 * @return boolean true if data should be refreshed, false if data should remain as is
843 */
844 public boolean isResetDataOnRefresh();
845
846 /**
847 * Setter for the reset data on refresh indicator
848 *
849 * @param resetDataOnRefresh
850 */
851 public void setResetDataOnRefresh(boolean resetDataOnRefresh);
852
853 /**
854 * Result of the conditionalRefresh expression, true if satisfied, otherwise false.
855 * Note: not currently used for any processing, required by the expression evaluator.
856 *
857 * @return the refresh
858 */
859 public boolean isRefresh();
860
861 /**
862 * @param refresh the refresh to set
863 */
864 public void setRefresh(boolean refresh);
865
866 /**
867 * Control names which will refresh this component when they are changed, added
868 * internally
869 *
870 * @return the refreshWhenChangedControlNames
871 */
872 public List<String> getRefreshWhenChangedControlNames();
873
874 }