With a ViewDecorator
you can wrap your Views in order to modify the behavior.
ViewDecorators
are useful for conditional aspects.
In the last section you learned how to enhance the generated HTML pages with debugging
comments by simply setting a flag. Implementing these comments directly in the templates would
be hard to maintain, hard to understand and distract from the actual functionality of the
template. A ViewDecorator
solves the problem much more effective. It can be
switched on and off in the preview and live CAE, respectively, and it has no impact on
template development.
Configuration
ViewDecorators
are declared as Spring beans and appended to the
viewDecorators
list in the CAE's view-services
. E.g. the
configuration for the DebugViewDecorator
looks like this:
<bean id="debugDecorator" class="com.coremedia.objectserver.view.DebugViewDecorator"> <description> Decorates view fragments with debug comments </description> </bean> <customize:append id="addCAEDebugDecorator" bean="viewDecorators" enabled="${view.debug.enabled}"> <description> Registers debug decorator </description> <list> <ref bean="debugDecorator"/> </list> </customize:append>
The activation of a ViewDecorator
is controlled by the enabled
flag
of the customizer. For the DebugViewDecorator
the view.debug.enabled
flag is by default set to true in the preview web application and to false in the live web
application.
Implementation
The actual ViewDecorator
interface consists of a single method
View decorate(View view)
While this interface is very flexible, it would be cumbersome to implement a decorating view
from scratch. You would have to deal with ServletView, TextView
and
XmlView
arguments and preserve the particular types for your decorating result
view. In order to simplify this, the CAE provides the abstract ViewDecoratorBase
which handles these type issues. If you extend the ViewDecoratorBase
, you only
have to implement getDecorator
and return a custom Decorator
. A
Decorator
consists of three decorate
methods for the View interfaces
ServletView, TextView
and XmlView
. The default implementations
simply delegate to the render methods of the original views. Custom overriding can enhance or
replace this behavior. For example, a decorate
method for ServletViews
might
look like this:
@Override
public void decorate(ServletView view, Object self, String viewName, HttpServletRequest request, HttpServletResponse response) {
try {
Writer out = response.getWriter();
out.write("<!-- Decoration before rendering -->");
view.render(self, viewName, request, response);
out.write("<!-- Decoration after rendering -->");
} catch (IOException e) {
throw new RuntimeException("Cannot decorate", e);
}
}