Implementation of GenericPortlet

My first impression of specification document is that it will be very complicated and only very few people or someone who is developing portlet engine will be able to understand it but surprisingly both Portlet Specification 2.0 and Portlet Specification 1.0 are very well written document.

What i like to do is download the portlet specification, which has a .pdf document describing specification and a src.zip file. This file has source code for javax.portlet files, or the Java classes/interfaces defined by the specification. Reading through these documents gives us a very good understanding of the specification.

Take a look at GenericPortlet.java that is part of src.zip which give us very good understanding of default portal implementation, Ex. doDispatch(), how the resource serving or action processing work

package javax.portlet;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.xml.namespace.QName;
public abstract class GenericPortlet implements Portlet, PortletConfig, EventPortlet, ResourceServingPortlet {

private transient PortletConfig config;

private transient Map processActionHandlingMethodsMap = new HashMap();
private transient Map processEventHandlingMethodsMap = new HashMap();
private transient Map renderModeHandlingMethodsMap = new HashMap();
public GenericPortlet() {
}
public void init(PortletConfig config) throws PortletException {
this.config = config;
cacheAnnotatedMethods();
this.init();
}
public void init() throws PortletException {
}

public void processAction(ActionRequest request, ActionResponse response) throws PortletException,
java.io.IOException {
String action = request.getParameter(ActionRequest.ACTION_NAME);

try {
// check if action is cached
Method actionMethod = processActionHandlingMethodsMap.get(action);
if (actionMethod != null) {
actionMethod.invoke(this, request, response);
return;
}
} catch (Exception e) {
throw new PortletException(e);
}

// if no action processing method was found throw exc
throw new PortletException("processAction method not implemented");
}
public void render(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
Object renderPartAttrValue = request.getAttribute(RenderRequest.RENDER_PART);
if (renderPartAttrValue != null) {
// streaming portal calling
if (renderPartAttrValue.equals(RenderRequest.RENDER_HEADERS)) {
doHeaders(request, response);
Collection nextModes = getNextPossiblePortletModes(request);
if (nextModes != null)
response.setNextPossiblePortletModes(nextModes);
response.setTitle(getTitle(request));
} else if (renderPartAttrValue.equals(RenderRequest.RENDER_MARKUP)) {
doDispatch(request, response);
} else {
throw new PortletException("Unknown value of the 'javax.portlet.render_part' request attribute");
}
} else {
// buffered portal calling
doHeaders(request, response);
Collection nextModes = getNextPossiblePortletModes(request);
if (nextModes != null)
response.setNextPossiblePortletModes(nextModes);
response.setTitle(getTitle(request));
doDispatch(request, response);
}
}

protected java.lang.String getTitle(RenderRequest request) {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getResourceBundle(request.getLocale()).getString("javax.portlet.title");
}


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);
}
}
}


protected void doView(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
throw new PortletException("doView method not implemented");
}


protected void doEdit(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
throw new PortletException("doEdit method not implemented");
}


protected void doHelp(RenderRequest request, RenderResponse response) throws PortletException, java.io.IOException {
throw new PortletException("doHelp method not implemented");
}


public PortletConfig getPortletConfig() {
return config;
}

public void destroy() {
// do nothing
}
public String getPortletName() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getPortletName();
}
public PortletContext getPortletContext() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getPortletContext();
}

public java.util.ResourceBundle getResourceBundle(java.util.Locale locale) {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getResourceBundle(locale);
}


public String getInitParameter(java.lang.String name) {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getInitParameter(name);
}


public java.util.Enumeration getInitParameterNames() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getInitParameterNames();
}

public Enumeration getProcessingEventQNames() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getProcessingEventQNames();
}

public Enumeration getPublishingEventQNames() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getPublishingEventQNames();
}

public Enumeration getSupportedLocales() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getSupportedLocales();
}
public Map getContainerRuntimeOptions() {
return config.getContainerRuntimeOptions();
}

public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException {
if (request.getResourceID() != null) {
PortletRequestDispatcher rd = getPortletConfig().getPortletContext().getRequestDispatcher(
request.getResourceID());
if (rd != null)
rd.forward(request, response);
}
}

public void processEvent(EventRequest request, EventResponse response) throws PortletException, IOException {
String eventName = request.getEvent().getQName().toString();

try {
// check for exact match
Method eventMethod = processEventHandlingMethodsMap.get(eventName);
if (eventMethod != null) {
eventMethod.invoke(this, request, response);
return;
} else {
// Search for the longest possible matching wildcard annotation
int endPos = eventName.indexOf('}');
int dotPos = eventName.lastIndexOf('.');
while (dotPos > endPos) {
String wildcardLookup = eventName.substring(0, dotPos + 1);
eventMethod = processEventHandlingMethodsMap.get(wildcardLookup);
if (eventMethod != null) {
eventMethod.invoke(this, request, response);
return;
}
if (dotPos == 0) {
break;
}
dotPos = eventName.lastIndexOf('.', dotPos - 1);
}
}
} catch (Exception e) {
throw new PortletException(e);
}

// if no event processing method was found just keep render params
response.setRenderParameters(request);
}

protected void doHeaders(RenderRequest request, RenderResponse response) {
return;
}


protected java.util.Collection getNextPossiblePortletModes(RenderRequest request) {
return null;
}

public Enumeration getPublicRenderParameterNames() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getPublicRenderParameterNames();
}


public String getDefaultNamespace() {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

return config.getDefaultNamespace();
}

private void cacheAnnotatedMethods() {
// cache all annotated and visible public methods
for (Method method : this.getClass().getMethods()) {
Annotation[] annotations = method.getAnnotations();
if (annotations != null) {
for (Annotation annotation : annotations) {
Class annotationType = annotation.annotationType();
if (ProcessAction.class.equals(annotationType)) {
String name = ((ProcessAction) annotation).name();
if (name != null && name.length() > 0)
processActionHandlingMethodsMap.put(name, method);
} else if (ProcessEvent.class.equals(annotationType)) {
String qname = ((ProcessEvent) annotation).qname();
if (qname == null || qname.length() <= 0) {
if (config == null)
throw new java.lang.IllegalStateException(
"Config is null, please ensure that your init(config) method calls super.init(config)");

String name = ((ProcessEvent) annotation).name();
if (name != null && name.length() > 0) {
qname = new QName(config.getDefaultNamespace(), name).toString();
processEventHandlingMethodsMap.put(qname, method);
}
} else
processEventHandlingMethodsMap.put(qname, method);
} else if (RenderMode.class.equals(annotationType)) {
String name = ((RenderMode) annotation).name();
if (name != null && name.length() > 0)
renderModeHandlingMethodsMap.put(name.toLowerCase(), method);
}
}
}
}
}
}

No comments: