001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.uif.component;
017
018import org.kuali.rice.krad.uif.modifier.ComponentModifier;
019import org.kuali.rice.krad.uif.service.ViewHelperService;
020import org.kuali.rice.krad.uif.view.View;
021
022import java.io.Serializable;
023import java.util.List;
024import java.util.Map;
025
026/**
027 * All classes of the UIF that are used as a rendering element implement the
028 * component interface. This interface defines basic properties and methods that
029 * all such classes much implement. All components within the framework have the
030 * following structure:
031 * <ul>
032 * <li>Dictionary Configuration/Composition</li>
033 * <li>Java Class (the Component implementation</li>
034 * <li>>JSP Template Renderer</li>
035 * </ul>
036 *
037 * There are three basic types of components:
038 * <ul>
039 * <li>Container Components: <code>View</code>, <code>Group</code></li>
040 * <li>Field Components: <code>Field</code></li>
041 * <li>Widget Components: <code>Widget</code></li>
042 * </ul>
043 *
044 * @author Kuali Rice Team (rice.collab@kuali.org)
045 * @see org.kuali.rice.krad.uif.container.Container
046 * @see org.kuali.rice.krad.uif.field.Field
047 * @see org.kuali.rice.krad.uif.widget.Widget
048 */
049public interface Component extends Configurable, Serializable, Ordered, ScriptEventSupport {
050
051    /**
052     * The unique id (within a given tree) for the component
053     *
054     * <p>
055     * The id will be used by renderers to set the HTML element id. This gives a
056     * way to find various elements for scripting. If the id is not given, a
057     * default will be generated by the framework
058     * </p>
059     *
060     * @return String id
061     */
062    public String getId();
063
064    /**
065     * Sets the unique id (within a given tree) for the component
066     *
067     * @param id - string to set as the component id
068     */
069    public void setId(String id);
070
071    /**
072     * Holds the id for the component that can be used to request new instances of that component from the
073     * {@link org.kuali.rice.krad.uif.util.ComponentFactory}
074     *
075     * <p>
076     * During component refreshes the component is reinitialized and the lifecycle is performed again to
077     * reflect the component state based on the latest updates (data, other component state). Since the lifecycle
078     * is only performed on the component, a new instance with configured initial state needs to be retrieved. Some
079     * component instances, such as those that are nested or created in code, cannot be obtained from the spring
080     * factory. For those the initial state is captured during the perform initialize phase and the factory id
081     * generated for referencing retrieving that configuration during a refresh
082     * </p>
083     *
084     * @return String bean id for component
085     */
086    public String getFactoryId();
087
088    /**
089     * Sets the factory id that backs the component instance
090     *
091     * @param factoryId
092     */
093    public void setFactoryId(String factoryId);
094
095    /**
096     * The name for the component type
097     *
098     * <p>
099     * 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}