Zied,
I guess what you really want to do is build the component tree in the
beginning of the JSF-Lifecycle also on the first request, so that you
can then run a normal lifecycle where all JSF phases are executed.
The beans are created whenever they are needed - on the initial
request, they are not needed until render-response.
Did I get you right?
regards,
Martin
On 6/21/07, Andrew Robinson <[EMAIL PROTECTED]> wrote:
> The issue, IMO, lies with <tc:in/> and not #{cat}. The value,
> #{cat.color} is being evaluated by the component in the render
> response phase, and thus when the variable resolver sees a base of
> cat, it finds it as a managed bean, and sees that it hasn't been
> instantiated yet, and thus creates it.
>
> If <tc:in/> is bound to a component that extends UIInput or implements
> EditableValueHolder, then it is the job of that component to decode
> the value during the processing of decoding. Typically what happens
> with UIInput:
>
> processDecodes calls decode
> decode calls the decode of the Renderer for the component
> the Renderer looks in the request parameters for whatever data it
expects
> if data is found, it sets the submitted value on the component
>
> processValidators is called which in tern, calls validate. If there is
> no submitted value (null), nothing happens. If there is a submitted
> value, validateValue is called. validateValue converts the submitted
> value to a local value using the converter (if any). (so
> getLocalValue() now returns a value). If any validation fails,
> renderReponse is called on the faces context and we skip to the render
> phase
>
> processUpdates is called. This now calls updateModel. This now gets
> the ValueBinding for the "value" attribute/property and calls set on
> it. This is where #{cat.color} will be resolved and set to the new
> value.
>
> As you can see, unless your component has any reason at all to use its
> value attribute before updateModel, then it will never be called (and
> thus your cat will not meow, er sorry, will not be created).
>
> If you are only seeing cats in the rendering then you are not getting
> to the updateModel phase (or your <tc:in /> isn't a UIInput
> component).
>
> So by your example, I don't see how this relates to backing bean
> instantiation but rather what <tc:in/> is and what the job of that
> component is.
>
> BTW, if you are not seeing the value getting updated, check for
messages.
>
> As for request attributes, I am still not seeing what you are using
> them for (are you using them to pass data between servlets, jsp pages
> and jsf views?).
>
> If for some business reason you need to force the instantiation of a
> component early, you could write a custom component and put it in the
> page that when restoreState is called (during the restore view), it
> calls:
>
> ValueBinding vb = getValueBinding("value");
> if (vb != null) vb.getValue(getFacesContext());
>
> That will force the "value" attribute to be evaluated, and if that is
> your #{cat.color}, the cat bean will be created.
>
> -Andrew
>
> On 6/21/07, Zied Hamdi <[EMAIL PROTECTED]> wrote:
> > Hi Andrew :-),
> >
> > The question wasn't well asked, I'm sorry. I will try my best:
> >
> > Today if JSF receives a request from a form that has in its component
list
> > the element ( <tc:in value="#{cat.color}"> ) and that none of the
scopes has
> > the attribute "cat" stored in it, the request parameter will rest as
is: no
> > action will be exerced in the UPDATE_MODEL_VALUES phase.
> >
> > And this will happen even if we have declared a backing bean with the
name
> > "cat" (in any of the scopes). The backing bean "cat" will be created
at the
> > RENDER_RESPONSE phase because it's there! that it will realize through
its
> > VariableResolverImpl that it needs a backing bean with that name and
that
> > it's still not instantiated.
> >
> > Now if the backing bean "cat" is session scoped, the first
RENDER_RESPONSE
> > will instantiate the bean, so it's not possible to have an incoming
form
> > request without having an already instantiated backing bean (as long
as the
> > request is coming from the same application).
> >
> > The problem is when the backing bean "cat" is request scoped: the
first
> > RENDER_RESPONSE will instantiate the bean and add it to the request
> > attributes, but when the request life cycle is finished (the page is
> > displayed), the attribute will die with its request. So when we submit
the
> > form, we are again in a blank situation (no bean in any scope), until
we
> > arrive to the RENDER_RESPONSE phase. Again there it's too late, the
> > INVOKE_APPLICATION phase has passed and no added value was done by the
JSF
> > framework.
> >
> > The idea is to detect the need for a backing bean before the
> > INVOKE_APPLICATION phase, and to have the bean populated at that
phase. So
> > insted of waiting until we reach the RENDER_RESPONSE phase, we can do
our
> > checks and instantiations in the UPDATE_MODEL_VALUES.
> >
> > Now let's discuss the bugs that may result from this design change:
> >
> > The developer may want to control the creation time of the backing
bean, in
> > that case, he doesn't need a backing bean but a standard request
attribute.
> > The developer may have its own attributes in the request and see them
> > overriden by JSF (because request parameters happen to be interpreted
by JSF
> > as a request for backing bean instantiation): we can log a warning in
this
> > case and do not instantiate the backing bean. But I saw in your that
you
> > agree it's not a good idea to have attribute naming conflicts, so the
> > warning can only be a compilation runtime extention.
> > I hope you understood what I mean, I'm sorry for writing so long mails
and
> > taking your time, but the idea seams important to me...
> >
> > Regards,
> > Zied Hamdi
> >
> >
> >
> > 2007/6/21, Andrew Robinson <[EMAIL PROTECTED]>:
> > > It sounds like you are simply asking about the name resolution from
> > > the EL engine. If that is the case, then there may be different
> > > options for you, but I am not sure if I still understand your use
case
> > > all the way.
> > >
> > > If it is about name resolution, then the best place I can send you
is
> > > to the MyFaces source code. If you open
> > >
> > > org.apache.myfaces.el.VariableResolverImpl
> > >
> > > You will see the source that is responsible for resolving JSF
variable
> > > names in the MyFaces implementation.
> > >
> > > When someone asks for "#{cat}", it will check in order:
> > >
> > > 1) built-in (facesContext for example)
> > > 2) request
> > > 3) session
> > > 4) application
> > > 5) managed bean
> > >
> > > Therefore if you have "cat" mapped in the servlet application scope
> > > and a bean named "cat", you will only get one from the servlet
> > > application scope and never the managed bean. If you have two
managed
> > > beans with the same name, one is booted and never will be returned
> > > (hence the warnings).
> > >
> > > Think of the managed beans as being registered in a Map. Only one
> > > value is possible.
> > >
> > > If you are having name conflicts, I would suggest using EL naming
> > > patterns. This could be XML namespace style, java package style, or
> > > your own custom style.
> > >
> > > So instead of "cat", you could use "requestscope-cat" or
> > > "request-com-mycomp-cat" or whatever.
> > >
> > > Now if you still want more functionality, then may I suggest looking
> > > into writing your own VariableResolver by extending the one from
> > > MyFaces or look into writing your own property resolvers (see
> > > faces-config information or other JSF specification information for
> > > information on these).
> > >
> > > Hope that helps some,
> > > Andrew
> > >
> > >
> > > On 6/20/07, Zied Hamdi <[EMAIL PROTECTED] > wrote:
> > > > Hi Andrew,
> > > >
> > > > Let's imagine we have declared a backing bean as request scoped
(say
> > cat).
> > > > On submit of a form that contains information related to that
bean, even
> > > > though we have specified in the form value attributes that we
point to a
> > > > bean with the given name (eg: value="#cat.color"), there isn't any
> > attempt
> > > > to verify if a backing bean with that name was declared (naturally
if it
> > > > isn't already in any scope).
> > > >
> > > > I'm new to JSF and I tried an example like this, thinking the
framework
> > will
> > > > recognise I'm trying to fill request parameters prefixed with
"cat" into
> > my
> > > > declared request scope bean with the same name, but when I aquired
> > control
> > > > "at the application scope" I didn't find any bean under the key
"cat" in
> > my
> > > > request.
> > > >
> > > > explanations : I'm not very good in english, maybe I was
misunderstood:
> > > >
> > > > There is nothing in the HttpServletRequest JavaDoc that says you
> > > > cannot set request attributes at any time once the request has
been
> > > > created:
> > > >
> > > >
> > > > I said that before the MVC frameworks, when we had only servlets
and
> > jsps,
> > > > it wasn't possible to intercept the request and add it attributes,
all
> > we
> > > > had was what comes from the HTTP protocol: parameters. Now that we
now
> > what
> > > > data model is expected on the other side, we can understand that
when a
> > > > parameter has a given naming pattern, it is designed to fill the
> > > > corresponding model data.
> > > > Instantiating beans before
> > > > they have been referenced would create performance and logic bugs
in
> > > > JSF applications.
> > > >
> > > >
> > > > Instantiating all the declared request beans will lead to even
worser
> > > > results than the actual, because for every request lifecycle we
will
> > have
> > > > all the possible beans in memory, plus the overcomputation of the
> > > > instantiation. What I meant was: by the name "pattern" of
UIComponent's
> > > > value attribute, we can understand that a UIComp is supposed to
fill the
> > > > field of a - page, request, session or application scoped - bean
with
> > the
> > > > name "cat" (again :-)). If we happen to have in our faces-config a
bean
> > with
> > > > the name "cat", and that theresn't any bean instanciated in the
server
> > > > memory (in any scope) with this same name, so we are the most
probably
> > > > trying to instanciate the declared bean and profit from all JSF
phases
> > to
> > > > have a validated and ready to use bean. If it happens that the
value
> > > > attribute didn't mean that bean (I mean not the one declared in
the
> > > > faces-config) than the user would rather rename his bean because
sooner
> > or
> > > > later, he will get bad surprises. (All the constraints it adds is
a sort
> > of
> > > > type checking, and no one will say that adding type checking is
bad for
> > safe
> > > > programming)
> > > >
> > > > I agree there are conditions to instantiate the bean without
adding bugs
> > > > (like putting a bean in the request, so hiding the original one
that was
> > in
> > > > (or will be added to) the session), but cases like this are very
> > probably
> > > > developper errors because using the same name in two scopes is
definitly
> > a
> > > > bad practice. Cases like this could be discouraged by warning
logs.
> > > > Otherwise, I don't see where there can be logic bugs, but the
question
> > needs
> > > > certainly more reflection.
> > > >
> > > >
> > > >
> > > > 2007/6/20, Andrew Robinson <[EMAIL PROTECTED]>:
> > > > > Beans are created on an as needed basis. Instantiating beans
before
> > > > > they have been referenced would create performance and logic
bugs in
> > > > > JSF applications.
> > > > >
> > > > > If you want to force the instantiation of beans at a given time,
> > > > > simply ask them to be created in a phase listener.
> > > > >
> > > > > The following code will force that an instance is created:
> > > > >
> > > > >
> > > >
> > application.createValueBinding("#{beanName}").getValue(facesContext);
> > > > >
> > > > > BTW, why can't you set a request attribute in a phase listener
in the
> > > > > before restore view phase?
> > > > >
> > > > > There is nothing in the HttpServletRequest JavaDoc that says you
> > > > > cannot set request attributes at any time once the request has
been
> > > > > created:
> > > > >
> > > > > http://tinyurl.com/29ypjz
> > > > >
> > > > > Even though I proposed a means to force the creating of request
beans,
> > > > > I don't see a valid use case for this. What are you trying to do
that
> > > > > would need to force a request bean to be created before a view
is
> > > > > restored? If you can answer that perhaps we can help find
another way
> > > > > of doing what you want with better design and performance
metrics.
> > > > >
> > > > > -Andrew
> > > > >
> > > > > On 6/20/07, Zied Hamdi <[EMAIL PROTECTED]> wrote:
> > > > > > Hi MyFaces people,
> > > > > >
> > > > > > I'd like to ask a question that leeded me to an interesting
> > concusion:
> > > > > >
> > > > > > Why now that we are in a "managed" environement can't we still
use
> > the
> > > > > > request attributes for incoming requests (to the server)?
> > > > > >
> > > > > > It's not complicted to have backward compatibility with the
servlet
> > > > > > specification, request attributes can't exist when we enter
the
> > > > > > Servlet.service() method. So now that we know that, we know
that we
> > > > can't
> > > > > > override an existing attribute if we create one in the restore
view
> > > > phase of
> > > > > > JSF. So why don't we create request scoped backing beans in
this
> > phase
> > > > so
> > > > > > that we avoid unnecessary session obesity.
> > > > > >
> > > > > > The idea is that with the current design of JSF, we must have
for
> > every
> > > > data
> > > > > > object (let's say data objects instead of DTO for objects that
go to
> > the
> > > > > > front end) an instance living in the session scope, and
everybody
> > knows
> > > > that
> > > > > > we don't matter if they are not reset to null when we don't
need
> > them.
> > > > The
> > > > > > use case is that we usually need one of them at a time. But
putting
> > them
> > > > in
> > > > > > the request scope isn't sufficient because they are not
transferred
> > to
> > > > the
> > > > > > next request where we need to get the user entred values. If
they
> > were
> > > > > > created in the restore view phase, they would live longer and
we
> > could
> > > > > > profit of their existence for all the cycle instead of having
them
> > at
> > > > the
> > > > > > moment the page is being displayed.
> > > > > >
> > > > > > I thing the way it's done today is historical: nothing was
managed
> > > > before
> > > > > > JSF and Struts, and we pay today for that historical technical
> > > > constraint
> > > > > > (that it isn't possible to pass attributes in the HTTP
protocol). To
> > > > compare
> > > > > > the problem: with Struts, the memory can be released from the
server
> > as
> > > > soon
> > > > > > as the action has finished its execution...
> > > > > >
> > > > > > --
> > > > > > Zied Hamdi
> > > > > > zatreex.sourceforge.net
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > >
> > > > Zied Hamdi
> > > > zatreex.sourceforge.net
> > >
> >
> >
> >
> > --
> >
> > Zied Hamdi
> > zatreex.sourceforge.net
>
--
http://www.irian.at
Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German
Professional Support for Apache MyFaces