Upload
whabicht
View
2.647
Download
0
Embed Size (px)
DESCRIPTION
A portlet-API based approach for application integration
Citation preview
1
A portlet-API based approach for application integration
Wolfgang HabichtMagnolia Conference, Basel
2009-09-10
2
Agenda
MotivationConceptThe portlet API and portlet basicsImplementation detailsMagnolia integrationReal world experiences & findings
3
Application Integration
Application integration is a generic problem§ Not CMS specific§ Depending on specific application issues
In general huge range of options§ Link, IFrame, “merged” content, integrated menu§ Adapting the application may be possible. Needed effort???
4
Discussed solution
Possible solution for§ Seamless integration into Magnolia§ Small, new applications
Portlet-API based approach offers:§ Simple and flexible API§ Dynamic flow over several pages§ Different applications on the same page§ Configuration in AdminCentral
5
Concept
§ Two-phase model
action render
Somewhere in filter chain While page rendering
Phase 1 Phase 2
6
Interaction overview
7
Portlet
§ JSR-168 (and JSR-286)§ Standard for developing portal components with Java§ Run in a Portlet Container / Portal Server
§ Action / render phase§ Simple API
8
interface Portlet{void init(PortletConfig);void processAction(ActionRequest, ActionResponse);void render(RenderRequest, RenderResponse);void destroy();
}
Portlet API (simplified)
interface ActionRequest extends PortletRequest{String getParameter(String);String[] getParameterValues(String name);Collection<String> getParameterNames();
}
interface PortletRequest{Object getAttribute(String);Collection<String> getAttributeNames();
}
9
interface Portlet{void init(PortletConfig);void processAction(ActionRequest, ActionResponse);void render(RenderRequest, RenderResponse);void destroy();
}
Portlet API (simplified)
interface ActionRequest extends PortletRequest{String getParameter(String);String[] getParameterValues(String name);Collection<String> getParameterNames();
}
interface PortletRequest{Object getAttribute(String);Collection<String> getAttributeNames();
}
10
Portlet API (simplified, continued)
interface PortletResponse{}
interface ActionResponse extends PortletResponse{void sendRedirect(String);void setRenderParameter(String, Object);HttpServletResponse handleResponseMyself();
}
11
Portlet API (simplified, continued)
interface RenderRequest extends PortletRequest{}
interface RenderResponse extends PortletResponse{PortletURL createActionURL(String);Writer getWriter();
}
interface PortletURL{void setParameter(String, String)void setParameter(String, String[])String toString();
}
12
Portlet API (simplified, continued)
interface RenderRequest extends PortletRequest{}
interface RenderResponse extends PortletResponse{PortletURL createActionURL(String);Writer getWriter();
}
interface PortletURL{void setParameter(String, String)void setParameter(String, String[])String toString();
}
13
public class DemoPortlet implements Portlet{
public void init(PortletConfig config) {String myJspTemplate = config.getParameters().get("myJspTemplate");
}
public void processAction(ActionRequest request, ActionResponse response) {String action = request.getAttribute(ActionRequest.ACTION_ATTRIBUTE_NAME);if ("redirect".equals(action))
response.sendRedirect(request.getParameter("target"));response.setRenderParameter("jsp", myJspTemplate);
}
public void render(RenderRequest request, RenderResponse response) {Writer out = response.getWriter();PortletURL url = response.createActionURL("new_action");out.write("<a href=\"" + url.toString() + "\">execute new_action</a>");
String jspTemplateName = (String) request.getAttribute("jsp");((WebContext) MgnlContext.getInstance()).include(jspTemplateName, out);
}
public void destroy() { }}
Portlet API usage example
14
Portlet API usage examplepublic class DemoPortlet implements Portlet{
public void init(PortletConfig config) {String myJspTemplate = config.getParameters().get("myJspTemplate");
}
public void processAction(ActionRequest request, ActionResponse response) {String action = request.getAttribute(ActionRequest.ACTION_ATTRIBUTE_NAME);if ("redirect".equals(action))
response.sendRedirect(request.getParameter("target"));response.setRenderParameter("jsp", myJspTemplate);
}
public void render(RenderRequest request, RenderResponse response) {Writer out = response.getWriter();PortletURL url = response.createActionURL("new_action");out.write("<a href=\"" + url.toString() + "\">execute new_action</a>");
String jspTemplateName = (String) request.getAttribute("jsp");((WebContext) MgnlContext.getInstance()).include(jspTemplateName, out);
}
public void destroy() { }}
15
Portlet API usage examplepublic class DemoPortlet implements Portlet{
public void init(PortletConfig config) {String myJspTemplate = config.getParameters().get("myJspTemplate");
}
public void processAction(ActionRequest request, ActionResponse response) {String action = request.getAttribute(ActionRequest.ACTION_ATTRIBUTE_NAME);if ("redirect".equals(action))
response.sendRedirect(request.getParameter("target"));response.setRenderParameter("jsp", myJspTemplate);
}
public void render(RenderRequest request, RenderResponse response) {Writer out = response.getWriter();PortletURL url = response.createActionURL("new_action");out.write("<a href=\"" + url.toString() + "\">execute new_action</a>");
String jspTemplateName = (String) request.getAttribute("jsp");((WebContext) MgnlContext.getInstance()).include(jspTemplateName, out);
}
public void destroy() { }}
16
createActionURL
Creates a link to the active portlet on the current page with specified action
§ Use the original URI of the current request as target address§ Set “action” and “portletId” parameters§ Add all (other) parameters of the current request
17
API extensions
ActionResponse {HttpServletResponse handleResponseMyself();
}
§ Portlet must (and can!) do any further request handling itself
§ “Generalization” of the redirect concept
18
Reply caching
§ Not every page load has an “action” and “render” phase!
Example: Page with a shopping cart and a weather forecast§ Remove one item of the shopping cart§ Change the displayed location in the weather gadgetà the last shopping cart action is “invalid”
A basic principle in the portlet context
Caching the RenderRequests for every portlet on the page allows independent portlet behaviour!
19
Implementation details
ActionRequestImpl:§ Special handling for action and uuid§ Needs access to HttpServletRequest
ActionResponseImpl:§ Needs access to HttpServletResponse§ Store redirect location if called
RenderRequestImpl:§ Needs ActionResponse in constructor
RenderResponseImpl:§ Needs HttpServletRequest and Writer in constructor§ createActionURL(…)
20
Implementation details (2)
PortletURLImpl:§ “Merge” parameters and action/portletId and create
parameter string
PortletConfig:§ Bean to provide the configuration (content2bean)§ classname§ portletId§ Description§ Map<String, String> parameters
21
Keeping the RenderRequest§ Put portlet id, portlet object and RenderRequest in a
container§ Store container in session§ G container is page-specific
On a request:§ Check for action command à do it!§ store in new container in session
§ Check for stored container entry§ move to new container and keep in session§ render it later during rendering
§ Call default action for missing entries and store them§ Remove old container
22
Default action
Provide a default action per portlet and page
§ Place the same portlet on different pages with different functionality (i.e. login, logout, display data, edit data, …)
§ Simple and intuitive menu integration§ Configure the default action on the page§ Allows one portlet per application
(in principle, different portlets could share the same data / state)
§ Transparent for the portlet!
23
Integration into Magnolia
Action phase:§ Add a portlet filter§ Alternative: action phase in template’s model (Mgnl 4.x)
(in the paragraph’s model it’s already too late)
Render phase:§ Called while rendering the paragraph containing the portlet
24
PortletFilter
Get all portlets of current page
Portlets found?
Remove old container
no
Get action
Have action?
Have container
entry?
yes
no
yes
Store in new containeryes
Call processAction
Get default action
More portlets?no
yes
no
Redirect?
no
yes
25
Render a portlet
§ JSP or Freemarker-template with only one tag: <mgnlportlet:portlet/>(integrated in Magnolia as paragraph)
§ Tag implementation:§ get portletId out of current content node§ get portlet object and render request out of container§ call portlet.render(…)
26
Configuration (backend)
§ configure portlet classname and portletId§ content2bean à pass any configuration value(s)
27
Configuration (frontend)
Portlet-Paragraph to add Portletsà choose portlet
and default action
Alternativ: “PortletApps” with preconfigured values
Portlet-specific configuration values:§ add subparagraph(s) inside your portlet§ access values by iterating through JCR nodes
28
Advanced configuration (portlet config dialog)
portlet config dialog
29
Advanced configuration (subparagraphs)
portlet config dialog
30
Interaction overview (repetition)
31
Putting all together: seamless Magnolia integration
text paragraph
portlet paragraph
applicational pages
CMS (only) pages
32
Unaddressed issues
§ Caching
§ Deployment
§ Several applications on same page may conflict (due to redirects)à how should the applications behave?
§ Integration of 3rd party frameworks
33
Real world experiences
§ Used in production§ Several applications integrated and live:§ virtual portfolio system§ serving personalized content (account information)§ CSV download of table content
(render into a CSV file instead of a HTML table)§ form editor (for Magnolia 3.5 / 3.6)§ wizards
34
Real world experiences (2)
§ Well-suited for small applications§ Multi-page setup is fragile§ Additional configuration inside the paragraph possible§ Use “normal” CMS page for additional content (help, …)§ Mixing of portlet-paragraphs and normal paragraphs on
same page possible
35
Findings
Intuitive and flexibleSimple API (no specific framework to use)Proper model phase supportFusing with Magnolia (menu, mix paragraphs, …)
Few programmer supportConfiguration dependencies (links to other pages)
Complexity of bigger applications
36
Any Questions?