A portlet-API based approach for application integration

Post on 08-May-2015

2.647 views 0 download

description

A portlet-API based approach for application integration

Transcript of A portlet-API based approach for application integration

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?