ICEFaces + Liferay : how to set value for public-render-parameter - liferay

ICEFaces + Liferay : I created two war file firstApp.war and secondApp.war file and deployed on liferay.
I want to implement, when I click submit button on firstApp.war application’s page , firstAppBacking bean should set some value in public-render-parameter so that I can get that value in secondApp.war application something like IPC. Please sugeest me how can i set the valiue in firstAppText.
<portlet-app ....>
<portlet>
<portlet-name>firstApp</portlet-name>
<display-name>First App</display-name>
<portlet-class>com.icesoft.faces.webapp.http.portlet.MainPortlet</portlet-class>
<init-param>
<name>com.icesoft.faces.VIEW</name>
<value>/jsp/firstApp.iface</value>
</init-param>
....
**<supported-public-render-parameter>firstAppText</supported-public-render-parameter>**
</portlet>
<public-render-parameter>
<identifier>firstAppText</identifier>
<qname xmlns:x="http://www.liferay.com/public-render-parameters">x:firstAppText</qname>
</public-render-parameter>

There are several ways to do that. First of all, the basic concepts are well described here.
As you can see, you can share data in different "contexts". One way is to share the data via the session by declaring shared-portlet-session-attribute in portlet.xml, e.g.
<shared-portlet-session-attribute>
<name>someName</name>
<java-class>com.some.class</java-class>
<shared-portlet-session-attribute>
Other ways to share data are:
- PortletSession
- PortletContext
- Page Parameters
- Portlet Events
The different ways are described in this book. I haven't yet tried all of them, therefore I cannot give more details now.

Related

MVCActionCommand vs MVCResourceCommand

I cant see the difference between MVCActionCommand vs MVCResourceCommand in coding OSGI portlets. The two interfaces seem to be interchangeable. With ActionResponse you can jump to a URL. With ResourceResponse, I can set the content to view the content on the page.
If i need to refresh the content on the page i.e refresh a particulat , should I use ActionReponse ? Most of the examples i found on the net make use of ResourceResponse resourceResponse.getWriter().write("Success");
How do I know when to use ResourceResponse and not ActionResponse?
Many thanks.
The origin of the separation lies within the Java Portlet LifeCycle (JSR 286). The command interfaces allow hooking into the lifecycle phases and provide the execution of your custom code.
There are three very different (in purpose) portlet url handlers:
MVCActionCommand to execute command, to change data, to perform actions (and do not return any to the frontend)
MVCRenderCommand to provide presentation & view to the client, to view results from a model selection, to render data through jsp/jsf/etc
MVCResourceCommand to provide the content in response: download files, download json csv excel pdf ...

JSF FlowScoped direct entry point

sorry if this question has been asked but i couldn't find the answer.
I've converted some spring beans to cdi #Named and set the scope to FlowScoped. I've done this to fix a problem where session scoped beans were shared across multiple tabs and breaking the application in previously opened tabs.
I've got it partly working but i'm running into an issue with the entry point for the FlowScoped beans.
All the examples i have found use a page with a button, this button has an action which navigates to the flow entry point (i've created a blank bean-flow.xml file). is there a way to enter a flow scope directly from a link or from a faces redirect? I kind of need this for two reasons. Or maybe there is another work around? I use spring security to login and it is set with a default-target-url="/search/search.xhtml". I've got around this by creating another page and just using the below to do a redirect on load
ConfigurableNavigationHandler configurableNavigationHandler =
(ConfigurableNavigationHandler) FacesContext.getCurrentInstance()
.getApplication().getNavigationHandler();
configurableNavigationHandler.performNavigation("search");
the above works but the below doesnt
FacesContext.getCurrentInstance().getExternalContext().redirect("/search/search.xhtml");
Idealy i would also like to be able type straight into the address bar
http://localhost:8080/searchApp/search/search.xhtml?searchcriteria=somecriteria
At the moment when i do that or the faces redirect i get an error
javax.servlet.ServletException: WebBeans context with scope type annotation #FlowScoped does not exist within current thread
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.apache.openejb.server.httpd.EEFilter.doFilter(EEFilter.java:65)
Any help at this point would be greatly appreciated.
It looks like you are trying to (ab)use a scope for which it was not directly meant to be used. Using the Deltaspike #WindowScoped is what you should use. It creates a scope per browser window or tab

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

Need help in sharing the portlet session data in liferay

Actually I am trying to share the data between 2 portlets in a 2 different plugin projects
Below are the steps I followed to share the data :
Step1: Create liferay plugin project named as Senderproj and created one portlet under Senderport then write below code in doView method
PortletSession session=req.getPortletSession();
String s="naresh";
session.setAttribute("gates",s,PortletSession.APPLICATION_SCOPE);
step2: Create liferay plugin project named as Receiverproj and created one portlet named as Receiverport then write below code in doView method
PortletSession ps = req.getPortletSession();
String tabName = (String)ps.getAttribute("gates",PortletSession.APPLICATION_SCOPE);
System.out.println("this is from doView of ipc receiver portlet"+tabName);
Step 3: I added the property in liferay-portlet.xml like below
<private-session-attributes>false</private-session-attributes>
When I drop two portlet in a portal page I got session value null in Receiverport.
can any one help out
Fist check that <private-session-attributes>false</...> is correctly set in both portles (sender and receiver).
Then, set and get session attributes using APPLICATION_SCOPE:
renderRequest.getPortletSession().setAttribute(
"name", "some value", PortletSession.APPLICATION_SCOPE
);
renderRequest.getPortletSession().getAttribute(
"name", PortletSession.APPLICATION_SCOPE
);
So far it seems that's what you're already doing.
If they are on the same page, we must ensure that they are loaded in the correct order. In Liferay this can be achieved by setting the render-weight. (In a real case it is better that they do not depend on the order in which they are loaded.)
<!-- Sender -->
<portlet>
<portlet-name>test-a</portlet-name>
<icon>/icon.png</icon>
<instanceable>true</instanceable>
<private-session-attributes>false</private-session-attributes>
<render-weight>3</render-weight>
...
</portlet>
<!-- Receiver -->
<portlet>
<portlet-name>test-b</portlet-name>
<instanceable>true</instanceable>
<icon>/icon.png</icon>
<private-session-attributes>false</private-session-attributes>
<render-weight>2</render-weight>
...
</portlet>
Besides, this link may be helpful:
Liferay Session Sharing Demystified

Rendering a layout template inside a Liferay portlet

I'm trying to render a layout template with nested portlets inside my custom Liferay portlet. Liferay's own "Nested Portlets" portlet does it using the RuntimePortletUtil in view.jsp:
RuntimePortletUtil.processTemplate(application, request, response, pageContext, out, velocityTemplateId, velocityTemplateContent);
When I do the same in my portlet however, I get the following error as soon as I put any portlets inside the layout template:
[render_portlet_jsp:157] javax.servlet.ServletException: File "/html/portal/render_portlet.jsp" not found
at org.apache.jasper.servlet.JspServlet.handleMissingResource(JspServlet.java:412)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:379)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
Can RuntimePortletUtil only be used in the Liferay portlet context or is there a way to get this working in my own portlet?
It looks like the implementation requires a file /html/portal/render_portlet.jsp which you might not have. It might be as simple as checking that file, see if you only need it or a few more resources.
However, instead of hunting that implementation down, I'd recommend looking at the underlying problem that you'd like to solve: IMHO Layout Templates are by far the easiest plugin types you can have in Liferay. All the examples I've seen for nesting Layout Templates looked more like a quick hack than like a proper solution. My recommendation is to provide some custom layout templates: It typically won't be a huge number of them, as increased numbers of layouts are typically increasingly confusing to the end user.
NestedPortlet is implemented inside Liferay's core and does not make any assumptions about running outside. While it might not be the best architectural decision to implement it depending on the server, nobody paid attention to make that code able to run outside of the portal - do yourself a favor and make your life easier by checking a different solution.

Resources