Showing posts with label portletmode. Show all posts
Showing posts with label portletmode. Show all posts

WebSphere portal server managed custom Portlet modes

A preference is modified by using setValue. This normally occurs at the personalized layer and therefore affects only the current user. WebSphere Portal uses two special custom modes from the set of predefined custom modes in the Java Portlet Specification to allow setting up the more general preference levels:


  • The edit_defaults custom portlet mode is used to work directly on the shared preferences. In this case the personalized preferences level is not available.

  • Similarly, the config mode is used to read and modify the administrator level of preferences.

  • The deployment descriptor level of preferences can only change when the portlet is redeployed with a modified portlet.xml. It cannot be modified by portlet code.



I built a sample portlet to demonstrate how you can use the edit_defaults and config mode supported by WebSphere Portal Server.

package com.webspherenotes.portlet.jsr286;

import java.io.IOException;
import java.util.ArrayList;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class WPSCustomPortletMode extends GenericPortlet{

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering CustomPortletMode.doView()");
response.setContentType("text/html");
response.getWriter().println("User Name "
+ request.getPreferences().getValue("userName", "Not Set"));
System.out.println("Exiting CustomPortletMode.doView()");
}

public void processAction(ActionRequest request, ActionResponse response)
throws PortletException, IOException {
System.out.println("Entering CustomPortletMode.processAction()");
String userName = request.getParameter("userName");
PortletPreferences preference = request.getPreferences();
preference.setValue("userName", userName);
preference.store();
System.out.println("Entering CustomPortletMode.processAction()");
}

protected void doEdit(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering CustomPortletMode.doEdit()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("/index.jsp").include(request, response);
System.out.println("Exiting CustomPortletMode.doEdit()");
}


protected void doEditDefaults(RenderRequest request, RenderResponse response)
throws PortletException, IOException{
System.out.println("Entering CustomPortletMode.doEditDefaults()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("/index.jsp").include(request, response);
System.out.println("Exiting CustomPortletMode.doEdit()");
System.out.println("Entering CustomPortletMode.doEditDefaults()");
}
protected void doConfig(RenderRequest request, RenderResponse response)
throws PortletException, IOException{
System.out.println("Entering CustomPortletMode.doConfig()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("/index.jsp").include(request, response);
System.out.println("Exiting CustomPortletMode.doConfig()");

}

PortletMode configMode = new PortletMode("config");
PortletMode editDefaultsMode = new PortletMode("edit_defaults");
protected void doDispatch(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering CustomPortletMode.doDispatch");
System.out.println("Requested portlet mode " + request.getPortletMode());
if(request.getPortletMode().equals(configMode)){
System.out.println("Request for config mode");
doConfig(request, response);
}else if(request.getPortletMode().equals(editDefaultsMode)){
System.out.println("Request for edit_defaults mode");
doEditDefaults(request, response);
}else{
super.doDispatch(request, response);
}

System.out.println("Exiting CustomPortletMode.doDispatch");
}
}


The WPSCustomPortletMode.java overrides doDispatch() and forwards control to corresponding custom modes. I am forwarding control to same index.jsp in edit, edit_defaults and config mode and all three of them allow user to submit a value for userName that i am storing in preference in processAction() method. Depending on the mode this value will get stored at different preference level.

This is how the portlet.xml file for WPCustomPortletMode looks like

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<portlet-name>WPSCustomPortletMode</portlet-name>
<display-name>WPS Custom Portlet Mode Portlet</display-name>
<portlet-class>com.webspherenotes.portlet.jsr286.WPSCustomPortletMode</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>edit</portlet-mode>
<portlet-mode>config</portlet-mode>
<portlet-mode>edit_defaults</portlet-mode>
</supports>
<portlet-info>
<title>WPS Custom Portlet Mode Portlet</title>
<short-title>WPS Custom Portlet Mode Portlet</short-title>
<keywords>WPS Custom Portlet Mode Portlet</keywords>
</portlet-info>
</portlet>
<custom-portlet-mode>
<description>Shared Settings mode</description>
<portlet-mode>edit_defaults</portlet-mode>
</custom-portlet-mode>
<custom-portlet-mode>
<description>Administrative mode</description>
<portlet-mode>config</portlet-mode>
</custom-portlet-mode>
</portlet-app>


I am defining two custom-portlet-modes here and for both of them the value of portal-managed equal to true, which is default value to indicate that these custom portlet modes are managed by WebSphere Portal

Non portal managed custom portlet modes

Portal vendors may define custom portlet modes for vendor specific functionality for modes that need to be managed by the portal. Portlets may define additional modes that don’t need to be managed by the portal and correspond to the VIEW mode from a portal point of view. The portlet must declare portlet modes that are not managed by the portal via the <portal-managed>false</portal-managed> tag. Portlet modes are considered portal managed by default.

I tried building a sample portlet, to demonstrate if i can use a non container managed portlet mode. My sample portlet has a clipboard mode and in that mode i am just displaying markup that says this clipbarod mode.


<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
<portlet-name>CustomPortletMode</portlet-name>
<display-name>Custom Portlet Mode Portlet</display-name>
<portlet-class>com.webspherenotes.portlet.jsr286.CustomPortletMode</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>clipboard</portlet-mode>

</supports>
<portlet-info>
<title>Custom Portlet Mode Portlet</title>
<short-title>Custom Portlet Mode Portlet</short-title>
<keywords>Custom Portlet Mode Portlet</keywords>
</portlet-info>
</portlet>
<custom-portlet-mode>
<description>Sample non portal managed mode</description>
<portlet-mode>clipboard</portlet-mode>
</custom-portlet-mode>

</portlet-app>



This is how my portlet.xml file looks like. I did add one custom-portlet-mode declaration for clipboard with value of portal-managed equal to false indicating that this mode is not managed by portal server.

Then i did create a CustomPortletMode.java like this

package com.webspherenotes.portlet.jsr286;

import java.io.IOException;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletURL;
import javax.portlet.RenderMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class CustomPortletMode extends GenericPortlet{

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering CustomPortletMode.doView()");
response.setContentType("text/html");
response.getWriter().println("Hello from View Mode");
/* PortletURL porteltURL = response.createRenderURL();
porteltURL.setPortletMode(new PortletMode("clipboard"));
response.getWriter().println("<a href='"+ porteltURL.toString()+"'>Go to clipboard Mode</a>"); */
System.out.println("Exiting CustomPortletMode.doView()");
}


protected void doClipboard(RenderRequest request, RenderResponse response)
throws PortletException, IOException{
System.out.println("Entering CustomPortletMode.doClipboard()");
response.setContentType("text/html");
response.getWriter().println("Hello from Clipboard Mode");
System.out.println("Exiting CustomPortletMode.doClipboard()");

}


PortletMode clipboardMode = new PortletMode("clipboard");
protected void doDispatch(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering CustomPortletMode.doDispatch");
System.out.println("Portlet Mode " + request.getPortletMode());
System.out.println("Is Config mode " + request.getPortletMode().equals(configMode));
System.out.println("Is Config mode " + request.getPortletMode().equals(clipboardMode));
if(request.getPortletMode().equals(clipboardMode)){
doClipboard(request, response);
}else{
super.doDispatch(request, response);
}
System.out.println("Exiting CustomPortletMode.doDispatch");
}

}


When i tried deploying this portlet in the WebSPhere Portal Server it did not show me a button to switch to Clipboard mode. I tried creating a link in the VIEW mode manually that will give me change to move to clipboard mode. But when i deployed in WPS the doView() started failing with this exception. It seems that WPS does not like concept of non portal managed custom mode.

If you want to use a Custom POrtlet mode in your portlet, then you will have to override the doDispatch() method of the GenericPortlet class and in that method check if the request is for custom portlet mode and if yes forward control to the appropriate method to handle that mode, if you dont do that GenericPortlet will throw exception



javax.portlet.PortletModeException: Can't set this PortletMode
at com.ibm.ws.portletcontainer.core.impl.PortletURLImpl.setPortletMode(PortletURLImpl.java:74)
at com.webspherenotes.portlet.jsr286.CustomPortletMode.doView(CustomPortletMode.java:20)
at javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:328)
at javax.portlet.GenericPortlet.render(GenericPortlet.java:233)
at com.ibm.ws.portletcontainer.invoker.impl.PortletFilterChainImpl.doFilter(PortletFilterChainImpl.java:128)
at com.ibm.wps.propertybroker.standard.filter.C2APortletFilter.doFilter(C2APortletFilter.java:183)
at com.ibm.ws.portletcontainer.invoker.impl.PortletFilterChainImpl.doFilter(PortletFilterChainImpl.java:120)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServlet.doDispatch(PortletServlet.java:573)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:114)
at com.ibm.isclite.container.collaborator.PortletServletCollaborator.doRender(PortletServletCollaborator.java:68)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:105)
at com.ibm.ws.portletcontainer.rrd.RRDServerPortletServletCollaborator.doRender(RRDServerPortletServletCollaborator.java:123)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:105)
at com.ibm.ws.portletcontainer.cache.CacheCollaborator.doRender(CacheCollaborator.java:92)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:105)
at com.ibm.wps.pe.pc.waspc.core.impl.PortletServletCollaboratorImpl.doRender(PortletServletCollaboratorImpl.java:156)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:105)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServlet.doDispatch(PortletServlet.java:273)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:82)
at com.ibm.isclite.container.collaborator.PortletServletCollaborator.doDispatch(PortletServletCollaborator.java:124)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:74)
at com.ibm.ws.portletcontainer.rrd.RRDServerPortletServletCollaborator.doDispatch(RRDServerPortletServletCollaborator.java:60)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:74)
at com.ibm.ws.portletcontainer.cache.CacheCollaborator.doDispatch(CacheCollaborator.java:74)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:74)
at com.ibm.wps.pe.pc.waspc.core.impl.PortletServletCollaboratorImpl.doDispatch(PortletServletCollaboratorImpl.java:121)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServletCollaboratorChainImpl.doCollaborator(PortletServletCollaboratorChainImpl.java:74)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServlet.dispatch(PortletServlet.java:208)
at com.ibm.ws.portletcontainer.invoker.impl.PortletServlet.service(PortletServlet.java:165)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1146)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1087)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:118)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:87)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:837)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:680)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:588)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:524)
at com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:122)
at com.ibm.ws.portletcontainer.webextension.PortletExtensionProcessor.handleRequest(PortletExtensionProcessor.java:93)
at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.include(WebAppRequestDispatcher.java:639)
at com.ibm.ws.portletcontainer.invoker.impl.PortletInvokerImpl.invoke(PortletInvokerImpl.java:235)
at com.ibm.ws.portletcontainer.invoker.impl.PortletInvokerCollaboratorChainImpl.doCollaborator(PortletInvokerCollaboratorChainImpl.java:78)
at com.ibm.ws.portletcontainer.cache.PortletInvokerCacheCollaborator.doRender(PortletInvokerCacheCollaborator.java:58)
at com.ibm.ws.portletcontainer.invoker.impl.PortletInvokerCollaboratorChainImpl.doCollaborator(PortletInvokerCollaboratorChainImpl.java:67)
at com.ibm.ws.portletcontainer.ext.PortletInvokerPerformanceCollaborator.invoke(PortletInvokerPerformanceCollaborator.java:313)
at com.ibm.ws.portletcontainer.ext.PortletInvokerPerformanceCollaborator.doInvoke(PortletInvokerPerformanceCollaborator.java:101)
at com.ibm.ws.portletcontainer.ext.PortletInvokerPerformanceCollaborator.invokePMI(PortletInvokerPerformanceCollaborator.java:163)
at com.ibm.ws.portletcontainer.ext.PortletInvokerPerformanceCollaborator.doInvoke(PortletInvokerPerformanceCollaborator.java:91)
at com.ibm.ws.portletcontainer.ext.PortletInvokerPerformanceCollaborator.doRender(PortletInvokerPerformanceCollaborator.java:74)
at com.ibm.ws.portletcontainer.invoker.impl.PortletInvokerCollaboratorChainImpl.doCollaborator(PortletInvokerCollaboratorChainImpl.java:67)
at com.ibm.ws.portletcontainer.invoker.impl.PortletInvokerImpl.render(PortletInvokerImpl.java:97)
at com.ibm.ws.portletcontainer.PortletContainerImpl.doRender(PortletContainerImpl.java:119)


When i deployed same code in the Apache Pluto i could go to Clipboard button like this

What is Portlet Mode

A portlet mode indicates the function a portlet is performing in the render method. Normally, portlets perform different tasks and create different content depending on the function they are currently performing. A portlet mode advises the portlet what task it should perform and what content it should generate. When invoking a portlet, the portlet container provides the current portlet mode to the portlet. Portlets can programmatically change their portlet mode when processing an action request.

The Portlet Specification defines three portlet modes, VIEW, EDIT, and HELP. The PortletMode class defines constants for these portlet modes. Every portlet must support VIEW mode and optionally it can support EDIT and HELP mode

RenderMode annotation

The doDispatch method of GenericPortlet class is modified in the Portlet Specification 2.0, so that now when it gets control first it checks if there is any method in your Portlet class which has @RenderMode annotation that matches the portlet mode of incoming request, if yes it forwards control to that method, if not then the doDispatch method will forward control to following methods

  • doView() for handling VIEW mode

  • doEdit() for handling EDIT mode

  • doHelp() for handling HELP mode



This is how the doDispatch() method in GenericPortlet class looks like

protected void doDispatch(RenderRequest request, RenderResponse response) throws PortletException,
java.io.IOException {
WindowState state = request.getWindowState();
if (!state.equals(WindowState.MINIMIZED)) {
PortletMode mode = request.getPortletMode();
// first look if there are methods annotated for
// handling the rendering of this mode
try {
// check if mode is cached
Method renderMethod = renderModeHandlingMethodsMap.get(mode.toString());
if (renderMethod != null) {
renderMethod.invoke(this, request, response);
return;
}
} catch (Exception e) {
throw new PortletException(e);
}

// if not, try the default doXYZ methods
if (mode.equals(PortletMode.VIEW)) {
doView(request, response);
} else if (mode.equals(PortletMode.EDIT)) {
doEdit(request, response);
} else if (mode.equals(PortletMode.HELP)) {
doHelp(request, response);
} else {
throw new PortletException("unknown portlet mode: " + mode);
}
}


I wanted to see how @RenderMode annotation works so i built a sample portlet like this, you can download it from here


package com.webspherenotes.portlet.jsr286;

import java.io.IOException;

import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class RenderModeAnnotationPortlet extends GenericPortlet{

@RenderMode(name="view")
public void handleViewMode(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ProcessActionAnnotationPortlet.handleViewMode()");
response.setContentType("text/html");
response.getWriter().println("<h3>View Mode Response</h3>");
System.out.println("Exiting ProcessActionAnnotationPortlet.handleViewMode()");
}

@RenderMode(name="edit")
public void handleEditMode(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ProcessActionAnnotationPortlet.handleEditMode()");
response.setContentType("text/html");
response.getWriter().println("<h3>Edit Mode Response</h3>");
System.out.println("Exiting ProcessActionAnnotationPortlet.handleEditMode()");
}

@RenderMode(name="help")
public void handleHelpMode(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ProcessActionAnnotationPortlet.handleHelpMode()");
response.setContentType("text/html");
response.getWriter().println("<h3>Help Mode Response</h3>");
System.out.println("Exiting ProcessActionAnnotationPortlet.handleHelpMode()");
}
}


If you want to use @RenderMode annotation, then you will have to do two things, first create a method with following signature


void (RenderRequest, RenderResponse) throws
PortletException, java.io.IOException;


Mark that method with @RenderMode(name="<modename>") attribute where value of name equals to name of the PortletMode that this method should handle

Supporting Multiple modes with Spring Portlet MVC Framework

In the HelloWorld Spring Portlet MVC Framework 3.0.1 entry i did build a simple HelloWorld Spring portlet which supports only VIEW mode.

Today i built a MultipleModesPortlet to demonstrate how you can support more than one mode using Spring MVC Framework. You can download the sample code from here

The MutlipleModesPortlet, support three modes VIEW, EDIT and HELP, It has one controller class for every mode. Ex ViewController class will handle every request for VIEW mode, the EditController class will handle every request for EDIT mode and HelpController class will handle every request for help mode. Only thing that Controller does is forward control to a JSP for rendering markup. The ViewController forwards control to view.jsp and similarly the other controller forward control to corresponding JSP.

This is how my ViewController.java looks like

public class ViewController extends AbstractController{
protected ModelAndView handleRenderRequestInternal(RenderRequest request,
RenderResponse response) throws Exception {
System.out.println("Entering ViewController.handleRenderRequest()");
ModelAndView modelAndView = new ModelAndView("view");
System.out.println("Exiting ViewController.handleRenderRequest()");
return modelAndView;
}
}


As you can see the ViewController class overrides handleRenderRequestInternal() method which gets call every time user tries to access the portlet in VIEW mode. Inside the handleRenderRequestInternal() method i am creating and returning ModelAndView("view") object. Which is equivalent to forwarding control to JSP for generating markup.

This is how my view.jsp looks like

<%@page language="java" contentType="text/html; %>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<portlet:defineObjects />
<h1>Hello from view.jsp</h1>

As you can see this JSP is generating static text.

Now the more important part is how to configure Spring Portlet MVC framework so that different controllers get called for different modes and the answer is that configuration goes in MultipleModes-portlet.xml like this

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<bean id="viewController"
class="com.webspherenotes.mvc.spring.action.ViewController" />
<bean id="editController"
class="com.webspherenotes.mvc.spring.action.EditController" />
<bean id="helpController"
class="com.webspherenotes.mvc.spring.action.HelpController" />
<bean id="portletModeHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="order" value="1" />
<property name="portletModeMap">
<map>
<entry key="view">
<ref bean="viewController" />
</entry>
<entry key="edit">
<ref bean="editController" />
</entry>
<entry key="help">
<ref bean="helpController" />
</entry>
</map>

</property>
</bean>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>


As you can see first i have created three bean definitions one for each Controller, this is the Controller class for com.webspherenotes.mvc.spring.action.EditController

Then the important part is portletModeHandlerMapping which has portletModeMap map that is used for mapping a Controller class to the mode. I am mapping view mode to viewController and edit mode to editController,..