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