Send parameter from Portlet doView to portal_normal.vm - liferay

I'm trying to send a parameter from Portlet doView function to portal_normal.vm
Is it possible? How can I send and receive it?
Sorry, but I can't see the way to do through request.
In doView I wrote
HttpServletRequest httpRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest));
httpRequest.setAttribute("hola", "hola");
And in the portal normal I tried with:
#set ($holas =$request.get('attributes').get('hola'))
#set ($holas2 = $request.getSession().getAttribute("hola"))
$holas
$holas2
but Velocity only shows $holas $holas2

This sounds like an overly specific plan to display some information outside of the portlet - but also well outside the portlet spec. Is it possible? Yes. Does it have limitations? Yes.
I didn't try it, but I'd argue that you don't have any guarantee that all render phases of all portlets have been finished before portal_normal.vm starts to be evaluated. Technically it's only necessary to have them finished once they are actually about to render. Render is not allowed to change any state - and you're implying that in your case it might do - because on render something else will be displayed.
It might make sense to rather assume that your theme has some DOM element that is available on the page. Then render some javascript that manipulates this DOM element. The dependency on the theme is the same, but you could also fall back to some default rendering in case you can't find the DOM element.
Alternatively, if you insist on your mode of operation. you might try to go through the servlet-session (portlet session won't help) as you have access to the HttpServletRequest from portal_normal.vm. Be warned though: Access to HttpServletRequest is nonstandard and not really portal-thinking

Related

When does mojarra adds a naming container to the list of optional parameters?

In the source of the class AjaxBehaviorRenderer (line 260) there is a line that apparently appends the NamingContainer Id to the list of optional parameters of mojarra.ab(...). I've never come across it so I'm curious as to when it is used:
RenderKitUtils.appendProperty(ajaxCommand, "com.sun.faces.namingContainerId", namingContainerId, true);
line 260
While working on spec issue 790 last week, which should solve a.o. Rendering other form by ajax causes its view state to be lost, how do I add this back?, this was explained to me by Neil Griffin, a portlet guy.
It appears that portlets can have multiple JSF views rendering to the same HTML document, each with its own view state. In portlets, there's a special UIViewRoot instance which implements NamingContainer. During regular rendering, all forms, inputs and commands will have IDs and names prefixed with the view's own client ID. This will work fine during synchronous postbacks. The portlet can this way identify the exact view to restore.
However, during asynchronous postbacks, the jsf.js will create a bunch of additional ajax-specific request parameters such as javax.faces.source, javax.faces.partial.event, etc. Those request parameter names are not prefixed with the view's own client ID. Therefore the portlet cannot associate them with a specific view. Hence the impl issue 3031.
There was another problem of view state identifiers in ajax responses not being properly namespaced this way. Therefore the portlet implementation had to customize the partial response writer in the so-called "JSF bridge". This will be taken into account during implementing spec issue 790. Instead of sniffing a "portlet environment" as in current implementation, there will be checks on UIViewRoot instanceof NamingContainer which is more flexible and portlet-independent. The Mojarra-specific com.sun.faces.namingContainerId will also be removed. Instead, this value will be rendered to <partial-response id="..."> so that the jsf.js can just extract from there.
All in all, not really important if you're only targeting servlet based environments.
As per balusC comment :
It's only interesting for portlet based apps (not servlet based apps).
I can't exactly explain why and what it is used for (a portlet/liferay
guy might), but the portlet specific feature is called "namespaced
parameters". See https://web.liferay.com/web/meera.success/blog/-/blogs/liferay-requires-name-spaced-parameters

change portlet mode programmatically in controller

I'm trying to write a Liferay MVC controller and I want to change the portlet mode in my renderer method.
The RenderRequest object does have a _portletMode property but there are no setter methods for that.
Note that I don't want to use java reflection to set that property because I'm concerned that it may affects something I'm not aware of!
You can't change portlet state (or mode) in the rander phase. Even if you can trick around, it's nonstandard, not supported for a reason.
You can however just display some other UI (e.g. jsp) during your render phase.
Changing state always involves one of the other phases.

ActionRequest vs RenderRequest

I've read here that actionrequest is only valid during the action phase and RenderRequest is only valid during the render phase. However if I set actionREquest.setAttribute("object", myobject) I can access this object from my JSP, which I understand is the render phase right? How is this possible and how does this fit with the answer I link?
While ActionRequest and RenderRequest are distinct classes/objects, they all relate to the same request handling cycle. The main difference is that ActionRequest allows you to change state, RenderRequest does not any more.
While only one portlet on the page can handle an action (per single HTTP request), all portlets on the page typically render to make up the whole markup of the page. That's what the separation of action/render brings you in the portlet world. Servlets didn't have this because one servlet was always meant to render the whole page on every single request anyway. Portlets can render (which they most often do) and they can change state (which they typically do in the action phase)
You shouldn't forget that after an action-phase, portlet lifecycles proceed toward render-phase.
Try to watch the image in this blog post (the first I found by a google search): http://haitaoblog.blogspot.it/2011/05/portlets-portal.html
So JSP can access to both attributes in request.
On the other hand, if you need to access in the render phase to an action RENDER parameter, you have to set it inside your action code
actionResponse.setRenderParameter("parameter-name", "value");

Xpages add a custom control that doesn't take up space (rendered versus loaded versus visible)

I have some custom controls that I want to include in Xpages, but I don't want them to be visible to the user or to take up space on the screen, as it is throwing my alignment off. I have looked at the properties rendered, loaded, and visible, but I don't really understand them and they don't seem to do what I want, which is to include some functionality but not change the layout.
I am sure there is a way to do this, but I can't figure it out.
Loaded means it won't be added to the component tree and only affects server-side functionality. Because it's not in the component tree (the server-side map of the page) it can't be passed to the browser or processed during partial refreshes. Rendered and visible are the same and mean they're in the component tree, so server-side processing can interact with them, but no HTML is passed to the browser for them. So you can't interact with them via CSJS. If you want it passed to the browser, available for CSJS but not visible to the user, you'll need to set the style as display:none. Another option is to put that style in a theme and allocate the themeId you choose to your custom control.

How to handle multiple submits before response is rendered?

It has been reported from testing that it is occasionally possible to press a button more than once if the response is not rendered fast enough, causing several invocations of the back-end code, which we do not want.
Application is Java EE 6 Web Profile using JSF 2.0 inside Glassfish 3.1.1.
I was wondering how this should be properly dealt with, and have thought of a few scenarios:
Submitting should disable all buttons using javascript while response is being rendered.
A flag in the Session scope saying it is already active, so the sensitive code is skipped and just moves on to the re-rendering of the response for the previous submit.
A synchronized block delaying the processing until the previous request have finished. Then it should be detected that it has been already processed and skipped.
Using one of the "new" scopes like conversion to handle the detection?
My immediate gut feeling is that the best approach is to have sensitive code blocks atomic, but then the problem is with rendering the correct response.
How should I approach this?
Submitting should disable all buttons using javascript while response is being rendered.
This is the easiest to implement in a generic manner. If you happen to use <f:ajax> exclusively, you could use the jsf.ajax.addOnEvent() to perform the job in a generic manner. An alternative JavaScript approach is to create kind of an "Loading" overlay which blocks the UI so that the enduser won't be able to interact with the underlying page anymore. This is basically an absolutely positioned hidden <div> which spans the entire viewport with some opacity (transparency). You could show it on submit and hide it on render. The keyword for this technique is "modal dialog". UI-oriented JSF component libraries have at least such a component already in their assortiment. E.g. PrimeFaces with a <p:dialog modal="true"> inside a <p:ajaxStatus>, or the <p:blockUI>
The only disadvantage is that it won't work if the client has JS disabled or don't use it and it thus won't prevent HTTP clients from double submits.
A flag in the Session scope saying it is already active, so the sensitive code is skipped and just moves on to the re-rendering of the response for the previous submit.
This is more known as "synchronizer token pattern" and has ever been requested for JSF by spec issue 559 which is currently on the ticket targeted for 2.2, but there doesn't seem to be any activity on it. The detection and blocking part is technically easy to implement, but the synchronous response handling part is not easy to implement if you want that the enduser ultimately retrieves the response as generated by the initial request. The asynchronous response handling is easy: just don't specify any components to update, i.e. empty the collection as returned by PartialViewContext#getRenderIds(). After all, this is more robust than using JS to disable the buttons or block the UI.
As far as I know, Seam 2 was the only who offered a reuseable JSF component for this, the <s:token>. I must however admit that this is an interesting idea for a new OmniFaces component. Maybe I will personally take a look at it.
A synchronized block delaying the processing until the previous request have finished. Then it should be detected that it has been already processed and skipped.
This is not easy to implement generically, this would require a change in all action methods to check if the job is already done. It also won't work if the webapp runs on multiple servers. A synchronizer token is easier as it would be performed before the action methods are invoked. A synchronizer token is also less expensive as you don't end up with multiple requests in the queue which would only cost threads/resources.
Using one of the "new" scopes like conversion to handle the detection?
This problem cannot be solved by playing around with managed bean scopes. Managed bean scopes serve a different purpose: the lifetime of the bean instance.
As Adrian mentioned, I would also use BlockUI. There is a BlockUI component from Primefaces. When you submit your forms through ajax, you could also use an overlay during the request. See Primefaces`s Ajax Status for an example.

Resources