I was wondering how I could create "component-scoped" beans, or so-to-say, "local variables inside a composite component" that are private to the instance of the composite component, and live as long as that instance lives.
Below are more details, explained with an example:
Suppose there is a "calculator" component - something that allows users to type in a mathematical expression, and evaluates its value. Optionally, it also plots the associated function.
I can make a composite component that has:
a text box for accepting the math expression
two buttons called "Evaluate", and "Plot"
another nested component that plots the function
It is evidently a self-contained piece of function; so that somebody who wants to use it may just say <math:expressionEvaluator />
But obviously, the implementation would need a java object - something that evaluates the expression, something that computes the plot points, etc. - and I imagine it can be a bean - scoped just for this instance of this component, not a view-scoped or request-scoped bean that is shared across all instances of the component.
How do I create such a bean? Is that even possible with composite components?
There is no "per-component instance" scope. But you can still achieve your desired effect.
Use a ViewScoped bean to do the evaluating and plotting - these functions are "stateless" and so are fed by your input.
Your input would be backed by a user supplied bean - in the same way a text box or calendar widget needs an input box bound to a user supplied bean. This holds the data that your "stateless" viewscoped bean acts on.
If you really wanted to keep everything contained in the component, I guess you could back the input with a ViewScoped bean that contains a map keyed by the input id. Not sure if that would work though.
Alternatively, you could also build a custom Java based UIComponent. Although these required a ridiculous amount of "moving parts" in JSF 1.x, in JSF 2.0 and Facelets they are actually not that much work to build.
Normally one should maybe be moderate in building custom Java based UIComponents, as for most use cases composite components are easier and more straight-forward. However, Java based UIComponents still have their use and doing actual calculations might be such a use.
Related
There are lot of materials out there differentiating value attribute and binding attribute in JSF.
I'm interested in how both approaches differ from each other. Given:
public class User {
private String name;
private UICommand link;
// Getters and setters omitted.
}
<h:form>
<h:commandLink binding="#{user.link}" value="#{user.name}" />
</h:form>
It is pretty straight forward what happens when a value attribute is specified. The getter runs to return the name property value of the User bean. The value is printed to HTML output.
But I couldn't understand how binding works. How does the generated HTML maintain a binding with the link property of the User bean?
Below is the relevant part of the generated output after manual beautification and commenting (note that the id j_id_jsp_1847466274_1 was auto-generated and that there are two hidden input widgets).
I'm using Sun's JSF RI, version 1.2.
<form action="/TestJSF/main.jsf" enctype="application/x-www-form-urlencoded"
id="j_id_jsp_1847466274_1" method="post" name="j_id_jsp_1847466274_1">
<input name="j_id_jsp_1847466274_1" type="hidden" value="j_id_jsp_1847466274_1">
Name
<input autocomplete="off" id="javax.faces.ViewState" name="javax.faces.ViewState"
type="hidden" value="-908991273579182886:-7278326187282654551">
</form>
Where is the binding stored here?
How does it work?
When a JSF view (Facelets/JSP file) get built/restored, a JSF component tree will be produced. At that moment, the view build time, all binding attributes are evaluated (along with id attribtues and taghandlers like JSTL). When the JSF component needs to be created before being added to the component tree, JSF will check if the binding attribute returns a precreated component (i.e. non-null) and if so, then use it. If it's not precreated, then JSF will autocreate the component "the usual way" and invoke the setter behind binding attribute with the autocreated component instance as argument.
In effects, it binds a reference of the component instance in the component tree to a scoped variable. This information is in no way visible in the generated HTML representation of the component itself. This information is in no means relevant to the generated HTML output anyway. When the form is submitted and the view is restored, the JSF component tree is just rebuilt from scratch and all binding attributes will just be re-evaluated like described in above paragraph. After the component tree is recreated, JSF will restore the JSF view state into the component tree.
Component instances are request scoped!
Important to know and understand is that the concrete component instances are effectively request scoped. They're newly created on every request and their properties are filled with values from JSF view state during restore view phase. So, if you bind the component to a property of a backing bean, then the backing bean should absolutely not be in a broader scope than the request scope. See also JSF 2.0 specitication chapter 3.1.5:
3.1.5 Component Bindings
...
Component bindings are often used in conjunction with JavaBeans that are dynamically instantiated via the Managed
Bean Creation facility (see Section 5.8.1 “VariableResolver and the Default VariableResolver”). It is strongly
recommend that application developers place managed beans that are pointed at by component binding expressions in
“request” scope. This is because placing it in session or application scope would require thread-safety, since
UIComponent instances depends on running inside of a single thread. There are also potentially negative impacts on
memory management when placing a component binding in “session” scope.
Otherwise, component instances are shared among multiple requests, possibly resulting in "duplicate component ID" errors and "weird" behaviors because validators, converters and listeners declared in the view are re-attached to the existing component instance from previous request(s). The symptoms are clear: they are executed multiple times, one time more with each request within the same scope as the component is been bound to.
And, under heavy load (i.e. when multiple different HTTP requests (threads) access and manipulate the very same component instance at the same time), you may face sooner or later an application crash with e.g. Stuck thread at UIComponent.popComponentFromEL, or Threads stuck at 100% CPU utilization in HashMap during JSF saveState(), or even some "strange" IndexOutOfBoundsException or ConcurrentModificationException coming straight from JSF implementation source code while JSF is busy saving or restoring the view state (i.e. the stack trace indicates saveState() or restoreState() methods and like).
Also, as a single component basically references the rest of the entire component tree via getParent() and getChildren(), when binding a single component to a view or session scoped bean, you're essentially saving the entire JSF component tree in the HTTP session for nothing. This will get really costly in terms of available server memory when you have relatively a lot of components in the view.
Using binding on a bean property is bad practice
Regardless, using binding this way, binding a whole component instance to a bean property, even on a request scoped bean, is in JSF 2.x a rather rare use case and generally not the best practice. It indicates a design smell. You normally declare components in the view side and bind their runtime attributes like value, and perhaps others like styleClass, disabled, rendered, etc, to normal bean properties. Then, you just manipulate exactly that bean property you want instead of grabbing the whole component and calling the setter method associated with the attribute.
In cases when a component needs to be "dynamically built" based on a static model, better is to use view build time tags like JSTL, if necessary in a tag file, instead of createComponent(), new SomeComponent(), getChildren().add() and what not. See also How to refactor snippet of old JSP to some JSF equivalent?
Or, if a component needs to be "dynamically rendered" based on a dynamic model, then just use an iterator component (<ui:repeat>, <h:dataTable>, etc). See also How to dynamically add JSF components.
Composite components is a completely different story. It's completely legit to bind components inside a <cc:implementation> to the backing component (i.e. the component identified by <cc:interface componentType>. See also a.o. Split java.util.Date over two h:inputText fields representing hour and minute with f:convertDateTime and How to implement a dynamic list with a JSF 2.0 Composite Component?
Only use binding in local scope
However, sometimes you'd like to know about the state of a different component from inside a particular component, more than often in use cases related to action/value dependent validation. For that, the binding attribute can be used, but not in combination with a bean property. You can just specify an in the local EL scope unique variable name in the binding attribute like so binding="#{foo}" and the component is during render response elsewhere in the same view directly as UIComponent reference available by #{foo}. Here are several related questions where such a solution is been used in the answer:
Validate input as required only if certain command button is pressed
How to render a component only if another component is not rendered?
JSF 2 dataTable row index without dataModel
Primefaces dependent selectOneMenu and required="true"
Validate a group of fields as required when at least one of them is filled
How to change css class for the inputfield and label when validation fails?
Getting JSF-defined component with Javascript
Use an EL expression to pass a component ID to a composite component in JSF
(and that's only from the last month...)
See also:
How to use component binding in JSF right ? (request-scoped component in session scoped bean)
View scope: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
Binding attribute causes duplicate component ID found in the view
each JSF component renders itself out to HTML and has complete control over what HTML it produces. There are many tricks that can be used by JSF, and exactly which of those tricks will be used depends on the JSF implementation you are using.
Ensure that every from input has a totaly unique name, so that when the form gets submitted back to to component tree that rendered it, it is easy to tell where each component can read its value form.
The JSF component can generate javascript that submitts back to the serer, the generated javascript knows where each component is bound too, because it was generated by the component.
For things like hlink you can include binding information in the url as query params or as part of the url itself or as matrx parameters. for examples.
http:..../somelink?componentId=123 would allow jsf to look in the component tree to see that link 123 was clicked. or it could e htp:..../jsf;LinkId=123
The easiest way to answer this question is to create a JSF page with only one link, then examine the html output it produces. That way you will know exactly how this happens using the version of JSF that you are using.
Is there an existing library that automatically creates a Java Swing form from a Properties (or Properties-like) object? i.e. shows 2 columns, as many rows as there are properties, properly justified Property names on the left, JTextFields for the values on the right.
I do not have access to the property names (or expected types) at compile time.
In addition, the solution must allow some value fields to be set read-only after construction.
A great solution would :
allow some property values to be specified as sensitive, requiring a JPasswordField
provide input format checking, e.g. against an object type (such as URL, Double, etc)
or by type-sensitive so that appropriate widgets (or buttons to bring up appropriate widgets) are used instead of JTextField for standard object types. e.g. JFileChooser for properties expected to be of a File type, SwingX Colour/Date selection, numerical format checking)
Getting into type-specific properties starts to sound like JavaBeans. I'd rather not go down the JavaBeans route unless there is a really easy - not a big framework - solution for this for an object that is a Javabean.
(I already know how to manually do this and could write a simple implementation myself that ignores sensitivity/type information - anyone answering along those lines will be shot down! I only want to know if such a beast already exists, preferably in a well maintained library)
UPDATE: related to Java Beans - creating an inspector window
No such thing exists. However, I wrote a rudimentary feature (and released it OSS) for https://github.com/fommil/zibaldone
We use JIDE, which not open-source.
If you don't mind that, take their Property Grid for a spin - it seem to match all your requirements.
Yes, I searched for questions about backing beans and I found many questions. I read them, and I get some parts of it but I need to ask another question, sorry.
After what I understand backing beans are needed because of JSF MVC pattern. Backing beans are the model. So if you have a page that displays a form, an image and a login box the backing beans will have getter/setter pairs for the data that needs to be exposed or changed in the view. And the backing beans will also have methods related to this such as what happen when you submit the form, login in etc.
So my question is if the statements above is correct, and the number of backing beans you make for the components above is dependent on how much code it is?
Would one backing bean exposing methods and getter/setter pairs for all components on this page be legal and "correct" (meaning that I don't do any wrong) in the same way as making 3 backing beans; one for each component would also be fine.
Does it all boil down to experience to see when you should separate vs. making one backing bean for each page, and also the logical part of it? I heard one guy made a backing bean for each component on the page but it sounds like you end up with a lot of small classes.
I would highly apprciate if somebody could verify and correct me.
It is legal for all components in a view to be bound to one managed bean for properties and actions. IDE tooling may encourage you to do this with a single backing bean.
From a class point of view however this approach lacks granularity and can make the managed beans difficult to test. If a class doesn't have a clearly defined purpose then it can be difficult to assert they are doing that job. See warning sign "Summing up what the class does includes the word “and”". All versions of JSF support dependency injection so it is relatively easy to rely on composition to assemble your managed beans.
This is a somewhat subjective topic and the answer depends on other factors (application scale; view design; page function.)
I am reading Core JavaServer Faces 3rd edition and I got a question about the encoding and decoding of JSF pages.
When the page is about to be rendered it will first go through the XHTML page containing JSF tags. Each JSF tag has a own tag handler class and they co-operate to make the component tree of that page. All other tags is ignored.
Each component has a own renderer that knows how to generate the HTML. Now the book says:
(This is a h:inputText tag)
Each component has a renderer that produces HTML output, reflecting the component state. The renderer of the UIInput object asks the JSF implementation to look up the unique ID and the current value fo the expression user.name.
The question is:
Why does the book say that the implementation asks for the current value of the expression user.name? I would expect that the implementation instead asked the component - in this case UIInput - which had some reference to this user bean instead? Because, doesn't that class "reflects" the JSF tag in code?
I probably have misunderstood the concept and I would like to learn it.
To get the output value of an EditableValueHolder like UIInput, a Renderer would typically call getValue(). This will generally return:
The value from getSubmittedValue() if input validation or conversion failed
The object set explicitly by calling setValue(Object) if any
The result of the value ValueExpression if any
The component defines behaviour. Ideally, it should be loosely coupled to the renderers, markup and data sources. The component doesn't care what its data source is - it doesn't have to be a managed bean. Getting and setting values is the responsibility of the ValueExpression.
What the ValueExpression evaluates to depends on the context.
Parameters passed to JSF components are basically EL (expression language) expressions, and evaluating those can be a lot more complex than accessing some reference - The JSF EL is a programming language of its own, with syntax and semantics only indirectly related to Java.
I would expect that the implementation instead asked the component ?
In my opinion, UIInput components and bean's properties are 2 distinctive things. They do not have any relationships with each other until we bind the value attribute of the UIInput component to a property of the bean.
In other words, UIInput components by themselves do not have anythings so called current values. They are simply a value displayer & getter. So, the renderer will have to ask the JSF implementation (which is usually the ManagedBean), for the value that the UIInput components should display.
... UIInput - which had some reference to this user bean instead
In general, the relationship between UIInput, a property and JSF implementation (ManagedBean) should look like this: UIInput - ManagedBean - bean properties. The renderer needs to communicate with the man in the middle (ManagedBean) to get what it wants because UIInput does not have a direct relationship with bean's properties.
The above are my current understanding. Please correct me if I'm wrong! :)
There are a couple of things that I am having a difficult time understanding with regards to developing custom components in JSF. For the purposes of these questions, you can assume that all of the custom controls are using valuebindings/expressions (not literal bindings), but I'm interested in explanations on them as well.
Where do I set the value for the valuebinding? Is this supposed to happen in decode? Or should decode do something else and then have the value set in encodeBegin?
Read from the Value Binding - When do I read data from the valuebinding vs. reading it from submittedvalue and putting it into the valuebinding?
When are action listeners on forms called in relation to all of this? The JSF lifecycle pages all mention events happening at various steps, but its not completely clear to me when just a simple listener for a commandbutton is being called
I've tried a few combinations, but always end up with hard to find bugs that I believe are coming from basic misunderstandings of the event lifecycle.
There is a pretty good diagram in the JSF specification that shows the request lifecycle - essential for understanding this stuff.
The steps are:
Restore View. The UIComponent tree is rebuilt.
Apply Request Values. Editable components should implement EditableValueHolder. This phase walks the component tree and calls the processDecodes methods. If the component isn't something complex like a UIData, it won't do much except call its own decode method. The decode method doesn't do much except find its renderer and invokes its decode method, passing itself as an argument. It is the renderer's job to get any submitted value and set it via setSubmittedValue.
Process Validations. This phase calls processValidators which will call validate. The validate method takes the submitted value, converts it with any converters, validates it with any validators and (assuming the data passes those tests) calls setValue. This will store the value as a local variable. While this local variable is not null, it will be returned and not the value from the value binding for any calls to getValue.
Update Model Values. This phase calls processUpdates. In an input component, this will call updateModel which will get the ValueExpression and invoke it to set the value on the model.
Invoke Application. Button event listeners and so on will be invoked here (as will navigation if memory serves).
Render Response. The tree is rendered via the renderers and the state saved.
If any of these phases fail (e.g. a value is invalid), the lifecycle skips to Render Response.
Various events can be fired after most of these phases, invoking listeners as appropriate (like value change listeners after Process Validations).
This is a somewhat simplified version of events. Refer to the specification for more details.
I would question why you are writing your own UIComponent. This is a non-trivial task and a deep understanding of the JSF architecture is required to get it right. If you need a custom control, it is better to create a concrete control that extends an exisiting UIComponent (like HtmlInputText does) with an equivalent renderer.
If contamination isn't an issue, there is an open-source JSF implementation in the form of Apache MyFaces.
Action listeners, such as for a CommandButton, are called during the Invoke Application phase, which is the last phase before the final Render Response phase. This is shown in The JSF Lifecycle - figure 1.
It is the only framework that I've
ever used where component creation is
a deep intricate process like this.
None of the other web frameworks
(whether in the .net world or not)
make this so painful, which is
completely inexplicable to me.
Some of the design decisions behind JSF start to make a little more sense when you consider the goals. JSF was designed to be tooled - it exposes lots of metadata for IDEs. JSF is not a web framework - it is a MVP framework that can be used as a web framework. JSF is highly extensible and configurable - you can replace 90% of the implementation on a per-application basis.
Most of this stuff just makes your job more complicated if all you want to do is slip in an extra HTML control.
The component is a composition of
several inputtext (and other) base
components, btw.
I'm assuming JSP-includes/tooling-based page fragments don't meet your requirements.
I would consider using your UIComponentELTag.createComponent to create a composite control with a UIPanel base and creating all its children from existing implementations. (I'm assuming you're using JSPs/taglibs and making a few other guesses.) You'd probably want a custom renderer if none of the existing UIPanel renderers did the job, but renderers are easy.
The best article I've found is Jsf Component Writing,
as for 2 where do I read the value for a value binding in your component you have a getter that looks like this
public String getBar() {
if (null != this.bar) {
return this.bar ;
}
ValueBinding _vb = getValueBinding("bar");
return (_vb != null) ? (bar) _vb.getValue(getFacesContext()) : null;
}
how did this get into the getValueBinding?
In your tag class setProperties method
if (bar!= null) {
if (isValueReference(bar)) {
ValueBinding vb = Util.getValueBinding(bar);
foo.setValueBinding("bar", vb);
} else {
throw new IllegalStateException("The value for 'bar' must be a ValueBinding.");
}
}