| Method from org.springframework.web.portlet.FrameworkPortlet Detail: |
protected ApplicationContext createPortletApplicationContext(ApplicationContext parent) throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Portlet with name '" + getPortletName() +
"' will try to create custom ApplicationContext context of class '" +
getContextClass().getName() + "'" + ", using parent context [" + parent + "]");
}
if (!ConfigurablePortletApplicationContext.class.isAssignableFrom(getContextClass())) {
throw new ApplicationContextException("Fatal initialization error in portlet with name '" + getPortletName() +
"': custom ApplicationContext class [" + getContextClass().getName() +
"] is not of type ConfigurablePortletApplicationContext");
}
ConfigurablePortletApplicationContext pac =
(ConfigurablePortletApplicationContext) BeanUtils.instantiateClass(getContextClass());
pac.setParent(parent);
pac.setPortletContext(getPortletContext());
pac.setPortletConfig(getPortletConfig());
pac.setNamespace(getNamespace());
pac.setConfigLocation(getContextConfigLocation());
pac.addApplicationListener(new SourceFilteringListener(pac, this));
postProcessPortletApplicationContext(pac);
pac.refresh();
return pac;
}
Instantiate the Portlet ApplicationContext for this portlet, either a default
XmlPortletApplicationContext or a custom context class if set.
This implementation expects custom contexts to implement
ConfigurablePortletApplicationContext. Can be overridden in subclasses. |
public void destroy() {
getPortletContext().log("Destroying Spring FrameworkPortlet '" + getPortletName() + "'");
if (this.portletApplicationContext instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) this.portletApplicationContext).close();
}
}
Close the ApplicationContext of this portlet. |
abstract protected void doActionService(ActionRequest request,
ActionResponse response) throws Exception
Subclasses must implement this method to do the work of action request handling.
The contract is essentially the same as that for the processAction
method of GenericPortlet.
This class intercepts calls to ensure that exception handling and
event publication takes place. |
protected final void doDispatch(RenderRequest request,
RenderResponse response) throws PortletException, IOException {
processRequest(request, response);
}
Delegate render requests to processRequest/doRenderService. |
abstract protected void doRenderService(RenderRequest request,
RenderResponse response) throws Exception
Subclasses must implement this method to do the work of render request handling.
The contract is essentially the same as that for the doDispatch
method of GenericPortlet.
This class intercepts calls to ensure that exception handling and
event publication takes place. |
public Class getContextClass() {
return this.contextClass;
}
Return the custom context class. |
public String getContextConfigLocation() {
return this.contextConfigLocation;
}
Return the explicit context config location, if any. |
public String getNamespace() {
return (this.namespace != null) ? this.namespace : getPortletName() + DEFAULT_NAMESPACE_SUFFIX;
}
Return the namespace for this portlet, falling back to default scheme if
no custom namespace was set. (e.g. "test-portlet" for a portlet named "test") |
public final ApplicationContext getPortletApplicationContext() {
return this.portletApplicationContext;
}
Return this portlet's ApplicationContext. |
public String getPortletContextAttributeName() {
return PORTLET_CONTEXT_PREFIX + getPortletName();
}
|
protected String getTitle(RenderRequest renderRequest) {
try {
return super.getTitle(renderRequest);
}
catch (NullPointerException ex) {
return getPortletName();
}
}
Overridden for friendlier behavior in unit tests. |
public String[] getUserinfoUsernameAttributes() {
return this.userinfoUsernameAttributes;
}
Returns the list of attributes that will be searched in the USER_INFO map
when trying to find the username of the current user |
protected String getUsernameForRequest(PortletRequest request) {
// Try the principal.
Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) {
return userPrincipal.getName();
}
// Try the remote user name.
String userName = request.getRemoteUser();
if (userName != null) {
return userName;
}
// Try the Portlet USER_INFO map.
Map userInfo = (Map) request.getAttribute(PortletRequest.USER_INFO);
if (userInfo != null) {
for (int i = 0, n = this.userinfoUsernameAttributes.length; i < n; i++) {
userName = (String) userInfo.get(this.userinfoUsernameAttributes[i]);
if (userName != null) {
return userName;
}
}
}
// Nothing worked...
return null;
}
Determine the username for the given request.
The default implementation first tries the UserPrincipal.
If that does not exist, then it checks the USER_INFO map.
Can be overridden in subclasses. |
protected void initFrameworkPortlet() throws PortletException, BeansException {
}
This method will be invoked after any bean properties have been set and
the ApplicationContext has been loaded.
The default implementation is empty; subclasses may override this method
to perform any initialization they require. |
protected ApplicationContext initPortletApplicationContext() throws BeansException {
ApplicationContext parent = PortletApplicationContextUtils.getWebApplicationContext(getPortletContext());
ApplicationContext pac = createPortletApplicationContext(parent);
if (!this.refreshEventReceived) {
// Apparently not a ConfigurableApplicationContext with refresh support:
// triggering initial onRefresh manually here.
onRefresh(pac);
}
if (isPublishContext()) {
// publish the context as a portlet context attribute
String attName = getPortletContextAttributeName();
getPortletContext().setAttribute(attName, pac);
if (logger.isDebugEnabled()) {
logger.debug("Published ApplicationContext of portlet '" + getPortletName() +
"' as PortletContext attribute with name [" + attName + "]");
}
}
return pac;
}
|
protected final void initPortletBean() throws PortletException, BeansException {
getPortletContext().log("Initializing Spring FrameworkPortlet '" + getPortletName() + "'");
if (logger.isInfoEnabled()) {
logger.info("FrameworkPortlet '" + getPortletName() + "': initialization started");
}
long startTime = System.currentTimeMillis();
try {
this.portletApplicationContext = initPortletApplicationContext();
initFrameworkPortlet();
}
catch (PortletException ex) {
logger.error("Context initialization failed", ex);
throw ex;
}
catch (BeansException ex) {
logger.error("Context initialization failed", ex);
throw ex;
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("FrameworkPortlet '" + getPortletName() + "': initialization completed in " + elapsedTime + " ms");
}
}
Overridden method of GenericPortletBean, invoked after any bean properties
have been set. Creates this portlet's ApplicationContext. |
public boolean isPublishContext() {
return this.publishContext;
}
Return whether to publish this portlet's context as a PortletContext attribute. |
public boolean isPublishEvents() {
return this.publishEvents;
}
Return whether this portlet should publish a PortletRequestHandledEvent at the end
of each request. |
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
this.refreshEventReceived = true;
onRefresh(((ContextRefreshedEvent) event).getApplicationContext());
}
}
|
protected void onRefresh(ApplicationContext context) throws BeansException {
// For subclasses: do nothing by default.
}
|
protected void postProcessPortletApplicationContext(ConfigurableApplicationContext pac) {
}
Post-process the given Portlet ApplicationContext before it is refreshed
and activated as context for this portlet.
The default implementation is empty. refresh() will
be called automatically after this method returns. |
public final void processAction(ActionRequest request,
ActionResponse response) throws PortletException, IOException {
processRequest(request, response);
}
Delegate action requests to processRequest/doActionService. |
protected final void processRequest(PortletRequest request,
PortletResponse response) throws PortletException, IOException {
long startTime = System.currentTimeMillis();
Throwable failureCause = null;
try {
if (request instanceof ActionRequest) {
doActionService((ActionRequest) request, (ActionResponse) response);
}
else {
doRenderService((RenderRequest) request, (RenderResponse) response);
}
}
catch (PortletException ex) {
failureCause = ex;
throw ex;
}
catch (IOException ex) {
failureCause = ex;
throw ex;
}
catch (Throwable ex) {
failureCause = ex;
throw new PortletException("Request processing failed", ex);
}
finally {
if (failureCause != null) {
logger.error("Could not complete request", failureCause);
}
else {
logger.debug("Successfully completed request");
}
if (isPublishEvents()) {
// Whether or not we succeeded, publish an event.
long processingTime = System.currentTimeMillis() - startTime;
this.portletApplicationContext.publishEvent(
new PortletRequestHandledEvent(this,
getPortletConfig().getPortletName(), request.getPortletMode().toString(),
(request instanceof ActionRequest ? "action" : "render"),
request.getRequestedSessionId(), getUsernameForRequest(request),
processingTime, failureCause));
}
}
}
Process this request, publishing an event regardless of the outcome.
The actual event handling is performed by the abstract
doActionService() and doRenderService() template methods. |
public void refresh() throws BeansException {
ApplicationContext pac = getPortletApplicationContext();
if (!(pac instanceof ConfigurableApplicationContext)) {
throw new IllegalStateException("Portlet ApplicationContext does not support refresh: " + pac);
}
((ConfigurableApplicationContext) pac).refresh();
}
Refresh this portlet's application context, as well as the
dependent state of the portlet. |
public void setContextClass(Class contextClass) {
this.contextClass = contextClass;
}
Set a custom context class. This class must be of type ApplicationContext;
when using the default FrameworkPortlet implementation, the context class
must also implement ConfigurablePortletApplicationContext. |
public void setContextConfigLocation(String contextConfigLocation) {
this.contextConfigLocation = contextConfigLocation;
}
Set the context config location explicitly, instead of relying on the default
location built from the namespace. This location string can consist of
multiple locations separated by any number of commas and spaces. |
public void setNamespace(String namespace) {
this.namespace = namespace;
}
Set a custom namespace for this portlet,
to be used for building a default context config location. |
public void setPublishContext(boolean publishContext) {
this.publishContext = publishContext;
}
Set whether to publish this portlet's context as a PortletContext attribute,
available to all objects in the web container. Default is true.
This is especially handy during testing, although it is debatable whether
it's good practice to let other application objects access the context this way. |
public void setPublishEvents(boolean publishEvents) {
this.publishEvents = publishEvents;
}
Set whether this portlet should publish a PortletRequestHandledEvent at the end
of each request. Default is true; can be turned off for a slight performance
improvement, provided that no ApplicationListeners rely on such events. |
public void setUserinfoUsernameAttributes(String[] userinfoUsernameAttributes) {
this.userinfoUsernameAttributes = userinfoUsernameAttributes;
}
Set the list of attributes to search in the USER_INFO map when trying
to find the username of the current user. |