My initial response is that this looks pretty cool. Not sure how it'll fit in with the JCP plans for JAX-RS MVC, but I like it in the JSF world.
___ Kito D. Mann | @kito99 | Author, JSF in Action Virtua, Inc. | http://www.virtua.com | JSF/Java EE training and consulting http://www.JSFCentral.com | @jsfcentral +1 203-998-0403 * Listen to the Enterprise Java Newscast: *http://w <http://blogs.jsfcentral.com/JSFNewscast/>ww.enterprisejavanews.com <http://ww.enterprisejavanews.com>* * JSFCentral Interviews Podcast: http://www.jsfcentral.com/resources/jsfcentralpodcasts/ * Sign up for the JSFCentral Newsletter: http://oi.vresp.com/?fid=ac048d0e17 On Wed, May 28, 2014 at 10:49 AM, Leonardo Uribe <lu4...@gmail.com> wrote: > Hi > > I have finally had some time to get a functional prototype out. For > the people interested, take a look at: > > https://github.com/lu4242/test-draft-actions-for-jsf > > The example does what we have discussed in this thread. This > is only a draft, and the intention is give us a better idea about this. > I have only tried it with MyFaces 2.2.3, but it should work with > Mojarra too. > > I think for JSF 2.2 we cannot do anymore. It is possible to imagine > other good tricks like a front controller and so on , but we need > to change the spec for that. > > The prototype is far to be fully functional, but it is simple and > clear enough to give the people an idea about what can be done > and if it is worth to do it or not. > > To run the prototype, just download the code and type in the > command line: > > mvn install > cd examples > mvn clean jetty:run > > look in localhost:8080 > > The next step after take a look at the prototype is propose a > vote to include it as a module for myfaces commons, but it will take > some time before that. > > Please share your reactions about this. Your opinions are welcomed. > > regards, > > Leonardo Uribe > > 2014-05-23 14:49 GMT+02:00 Leonardo Uribe <lu4...@gmail.com>: > > Hi > > > > DR>> *Regarding #{ma:sourceActionURL('renderOptions') : render the URL > > of the action > > DR>> How is the URL rendered? Through the RequestMapping of the method > > as defined with the Bean? > > DR>> And the attribute, params of the action defined are appended to the > URL? > > > > Good question Dora. > > > > For #{ma:sourceActionURL(...)} the idea is call > > viewHandler.getActionURL(...), append a custom query parameter called > > 'oamva', and then call externalContext.encodeActionURL(...) , so the > > final link could look like this: > > > > /myfaces-mvc-examples/sayhello.jsf?jfwid=-5tba0312z&oamva=button > > > > In this case we are adding a query param to a url that will be used > > later in a POST, I think it is justified the use of a query param for > > the command activation. The only thing to take care here is be sure > > that the target component should fulfit some strict conditions, by > > security reasons. Anyway, without view state the POST will not work. > > > > Theoretically, only the client window and the action must be append in > > the URL, the other parameters like the view state, the input and so on > > must be provided by the user manually. After all, this is something of > > "low level", you want to have some flexibility at the time of define > > the parameters, for some users that could be important. > > > > For ma:getLink, it uses the same logic for h:link, which is in > > org.apache.myfaces.shared.renderkit.html.util.OutcomeTargetUtils > > method getOutcomeTargetHref(facesContext, target). > > > > DR>> For $.post with this URL, when its not appended with the > > attribute or params, execute="@form" attribute of ma:defineAction is > > not used. > > DR>> Purpose of this attribute out of scope of jQuery post? > > > > A declaration of ma:defineAction component is always, always required, > > without exceptions. This component will always decoded and its action > > processed. > > > > Most of the time > > $(document.getElementById("#{ma:parentFormId()}")).serialize() will do > > the job of add all input fields in the current form, so in that sense > > it works as an f:ajax request. In JSF no matter where the f:ajax > > request is, all the input fields of the parent form are sent, no > > matter what the "execute" parameter says. By 2.2 spec, you know you > > should always provide javax.faces.ViewState and > > javax.faces.ClientWindow, so I think that's clear enough. In that > > sense, it works just like f:ajax, but there is no render response > > phase, instead the action defines what to render. It is responsibility > > of the user to send the proper parameters, of the components that will > > be processed. > > > > DR>> *autocomplete is transient and hence its not required to update > viewstate > > > > I don't get what do you want to say. This is different from a form > > POST, this is a javascript POST, autocomplete doesn't have sense in > > this case. > > > > DR>> Script integration via jQuery with action is flowless and awesome! > > > > That's the idea. Something easy to use and flexible enough to cover > > those rare cases where you need to get your hands dirty with > > javascript, but without break the nice part of JSF abstraction, which > > is be independent of protocols. > > > > These days I haven't had enough time to get it done, but I hope in > > this weekend to get something out and publish a draft on my Github > > account, so the people interested can take a look and see if these > > ideas are good enough and later vote for create a new module, with > > something clear in mind. This is trial and error, and nothing is > > certain, so no matter if something looks fancy or cool, a community > > vote is required to move forward from that point. > > > > regards, > > > > Leonardo Uribe > > > > 2014-05-21 18:34 GMT+02:00 Dora Rajappan <dorarajap...@yahoo.com>: > >> > >> *Regarding #{ma:sourceActionURL('renderOptions') : render the URL of the > >> action > >> How is the URL rendered? Through the RequestMapping of the method as > defined > >> with the Bean? > >> And the attribute, params of the action defined are appended to the URL? > >> > >> For $.post with this URL, when its not appended with the attribute or > >> params, execute="@form" attribute of ma:defineAction is not used. > >> Purpose of this attribute out of scope of jQuery post? > >> > >> *autocomplete is transient and hence its not required to update > viewstate > >> > >> Script integration via jQuery with action is flowless and awesome! > >> > >> Regards, > >> Dora Rajappa > >> > >> On Monday, May 19, 2014 9:13 PM, Leonardo Uribe <lu4...@gmail.com> > wrote: > >> > >> > >> Hi > >> > >> DR>> How about @ViewAction("/section1", action="exportExcel") > >> > >> It will not work because you can't change the annotation definition. > >> In other words, we should make "action" parameter a reserved one. > >> Also, the parameter by itself can have a converter or validator or a > >> EL binding, so you need to define that too. That's why @ViewParam or > >> something that define the parameter is required. > >> > >> regards, > >> > >> Leonardo > >> > >> 2014-05-15 14:30 GMT+02:00 Dora Rajappan <dorarajap...@yahoo.com>: > >>> <a href="#{ma:getLink('/section1/mypage?action=exportExcel')}">Export > >>> excel</a> can work > >>> when the definition is > >>> @ViewAction("/section1/*", action="exportExcel") > >>> How about > >>> @ViewAction("/section1", action="exportExcel") > >>> On Wednesday, May 14, 2014 12:01 AM, Dora Rajappan > >>> <dorarajap...@yahoo.com> > >>> wrote: > >>> How will <a href="#{ma:getLink('mypage?action=exportExcel')}">Export > >>> excel</a> > >>> work when ViewAction is not defined as > >>> > >>> @ViewAction(value="/sayhello.xhtml", > >>> params= { > >>> @ViewParam(name="action", > >>> expectedValue="exportExcel") > >>> }) > >>> public void method3(@ViewParam String param1, > >>> @ViewParam("someOther") Integer param2) > >>> { > >>> but as @ViewAction("/section1/*", action="exportExcel") > >>> Is the latter not supported now? > >>> > >>> facelet function getLink for action processing is not a bad idea. > >>> On Sunday, May 11, 2014 11:52 PM, Leonardo Uribe <lu4...@gmail.com> > wrote: > >>> Hi > >>> > >>> Ok, I think the idea about @ViewAction and @ViewParam is clear, I have > >>> implemented a fast prototype and it works well, there is a lot of > things > >>> we > >>> can do for improvement, however we should focus the attention in other > >>> areas so we can give the module a better structure. > >>> > >>> The next thing we need is how to combine javascript with JSF, > specifically > >>> in cases like this: > >>> > >>> <input id="search"/> > >>> <script type="text/javascript"> > >>> $('#search').autocomplete({ > >>> source: "#{some EL that return a link to an action goes here}" > >>> }); > >>> </script> > >>> > >>> The idea is provide an input box and then write some javascript lines > to > >>> make the component an autocomplete box, but the problem is we need to > >>> provide > >>> a URL that can be used to retrieve the values to fill the box. In my > >>> opinion, > >>> mix EL and javascript is the best in these cases, but things get > complex > >>> quickly when you need to provide parameters and so on. So I would like > to > >>> propose these facelet functions (better with examples): > >>> > >>> <a href="#{ma:getLink('mypage?action=exportExcel')}">Export > excel</a> > >>> > >>> and > >>> > >>> <ma:defineLink id="mylink"> > >>> <f:param name="action" value="renderMessage"/> > >>> </ma:defineLink> > >>> > >>> <a href="#{ma:getLinkFrom('mylink')}">Render url from EL > expression</a> > >>> > >>> #{ma:getLink(...)} work just like h:link but receives the outcome as > >>> parameter. > >>> The function append the request path and the client window id, so the > >>> final > >>> generated link will be something like this: > >>> > >>> > >>> > http://localhost:8080/myfaces-mvc-examples/sayhello.jsf?id=5&jfwid=1di8uhetf9&action=exportExcel > >>> > >>> #{ma:getLinkFrom(...)} just inject the link from a component that works > >>> just > >>> like h:link but it is just a wrapper, so the user can customize the > >>> parameters, > >>> when the EL function is called, the link is rendered taking the > parameters > >>> in the definition. The outcome by default is the page itself. > >>> > >>> > >>> Please note this proposal is something different from the one that > suggest > >>> to > >>> create the link just pointing to the method in the bean like > >>> #{ma:getLink('mybean', 'mymethod', params)}. After thinking about it, > the > >>> problem with that approach is the difficulty to do the match between > the > >>> link > >>> to generate and the method. EL does not consider annotated methods, so > it > >>> is > >>> not possible to scan the annotations from the EL unless you do a bypass > >>> over > >>> CDI. > >>> > >>> I think the approach proposed is something simple to understand, and it > >>> has > >>> the advantage that you can isolate the declaration of the link from the > >>> rendering, so the final javascript code will be easier to read. > >>> > >>> Finally we need something for the POST case, so the idea is append > >>> something > >>> like this: > >>> > >>> <form action="#{ma:encodeActionURL()}" > >>> method="post" > >>> enctype="application/x-www-form-urlencoded"> > >>> .... > >>> </form> > >>> > >>> #{ma:encodeActionURL()} do what h:form does for encode the action url. > >>> Then, > >>> it is responsibility of the user to provide the view state and client > >>> window > >>> token in the request as data, so the postback can be processed > properly. > >>> In this case, the idea is the view scope will be available, but the > >>> component > >>> tree state will not be updated when POST goes back to the client, so > any > >>> changes on the component tree in the action will be ignored. > >>> > >>> JSF does not make any difference between GET and POST, so viewParam > will > >>> work just the same. What defines a postback in JSF is if the view state > >>> field is in the request or not. Theoretically, use #{ma:getLink(...)} > >>> should > >>> work too, but I think there are different cases. > >>> > >>> There is a contradiction in this case. Send a POST, provide the view > state > >>> token, do not restore the view but restore the view scope bean. The > >>> problem > >>> is > >>> after you make changes on the view scope beans you need to save those > >>> changes, > >>> and that could mean update the view state token, even if the beans are > >>> stored > >>> in the server (remember the beans can be serialized, for example in a > >>> cluster). > >>> > >>> If we take a look at the proposed goals: > >>> > >>> 1) possibility to use a normal JSF lifecycle for the first GET request > >>> 2) allow action handling and custom response for POST actions > >>> 3) normal action handling like in asp.net MVC + a EL util function to > >>> generate the action URL > >>> > >>> we cannot really make number 2 exactly as POST actions. It doesn't fit > >>> because > >>> "... JSF's core architecture is designed to be independent of specific > >>> protocols and markup. ...". > >>> > >>> Really the problem proposed in number 2 is not simple and we should > >>> analyze > >>> it > >>> carefully. In which cases do we really need that kind of action > handling? > >>> If > >>> we are thinking for example in a JSF component that defines an endpoint > >>> with > >>> a > >>> custom response (for example a captcha component), we need a component > >>> oriented > >>> solution, something closer as what we have for ajax. What we have > proposed > >>> here with @ViewAction works in the case the user needs to define an > >>> endpoint > >>> at the "page" level. > >>> > >>> Really the big problem is how to hook the javascript code, so the > updates > >>> of > >>> the view state on the client side can be properly chained. For example > in > >>> MyFaces there is a queue for all ajax request, but we need that the > >>> actions > >>> sent that requires update the view state can be synchronized with that > >>> ajax queue too. > >>> > >>> I think what we have already is enough useful for a module. After all, > we > >>> don't need to solve all the problems at once. > >>> > >>> Suggestions are welcomed. > >>> > >>> regards, > >>> > >>> Leonardo Uribe > >>> > >>> 2014-05-05 0:05 GMT+02:00 Leonardo Uribe <lu4...@gmail.com>: > >>>> Hi Thomas > >>>> > >>>> TA>> AFAIR now, your solutions seems to be just a replacement for > >>>> f:viewAction > >>>> TA>> + allow different handlers via URL parameters. > >>>> TA>> Its sound really lightweight and easy actually :) > >>>> TA>> Does it cover all our requirements from the earlier mails? > >>>> TA>> > >>>> > >>>> I think so, but we need to write some examples to be sure that the > syntax > >>>> cover > >>>> all cases. > >>>> > >>>> Instead put a Front Controller on top of the lifecycle, we can go with > >>>> this approach > >>>> and provide some methods to call JSF algorithm inline. We already have > >>>> some > >>>> code in VDL.createComponent(...) that does inline compilation, so it > >>>> is not really > >>>> hard to write the necessary lines to do so (if the code is properly > >>>> implemented > >>>> of course). The idea could be provide something like: > >>>> > >>>> JSFUtils.generatePage("/mypage.xhtml", ....) > >>>> > >>>> and internally we call the algorithm, and deal with the potential > >>>> problems. > >>>> > >>>> So, if the user really wants to go with a MVC framework and use JSF as > >>>> template > >>>> engine, it will be as simple as write the adapter for the framework. > >>>> We should not > >>>> reinvent the wheel in this case. So, all other cases not supported by > >>>> f:viewAction/f:viewParam, which should be very, very few, should be > done > >>>> writing > >>>> a servlet or using an MVC framework like JAX-RS, and if necessary > calling > >>>> JSF at render time. > >>>> > >>>> The nice part about reuse f:viewAction logic is that is something > >>>> proved, everybody > >>>> knows how it works, we are just extending the syntax to define > >>>> f:viewAction in > >>>> a more familiar way. In practice we need to write a custom component > >>>> extending > >>>> UIViewAction, but that's something easy, I have already done it and it > >>>> works. > >>>> > >>>> That should cover most of the cases. There are other cases that are > >>>> indirectly > >>>> related to this one, but after some review, it doesn't seem to be so > >>>> interesting > >>>> or useful, or can be too complex to implement properly, so we need to > >>>> wait and push > >>>> it into the next spec. Sometimes less is more. Let's see what happen. > >>>> > >>>>>> Whats the syntax for multiple params? -> > >>>>>> params="action=exportExcel&someOther=string"? > >>>>>> Maybe we could think about a more typesafe and readable way. e.g. > >>>>>> > >>>>>> @ViewAction(value="my.xhtml", params = { > >>>>>> @ViewParam(name="action", value="exportExcel"), > >>>>>> @ViewParam(name="someOther", value="string") > >>>>>> }) > >>>> > >>>> I was thinking about this: > >>>> > >>>> @ViewAction(value="/sayhello.xhtml", params="action=exportExcel") > >>>> public void method3(@ViewParam String param1, > >>>> @ViewParam("someOther") Integer param2) > >>>> { > >>>> > >>>> The method has two parts: one define the parameters that should be > >>>> present > >>>> and the other define the activation conditions, in this case, when > >>>> action=exportExcel. Please note to make @ViewParam("someOther"), we > >>>> need to associate value to the key name. So we could do something > >>>> like this: > >>>> > >>>> @ViewAction(value="/sayhello.xhtml", > >>>> params= { > >>>> @ViewParam(name="action", > >>>> expectedValue="exportExcel") > >>>> }) > >>>> public void method3(@ViewParam String param1, > >>>> @ViewParam("someOther") Integer param2) > >>>> { > >>>> > >>>> I think in this way it looks better. Thanks for the suggestion. > >>>> > >>>> regards, > >>>> > >>>> Leonardo > >>> > >>> > >>> > >>> > >> > >> >