OCPSoft.com - Simple SolutionsCommunity Documentation
As a modern web-framework, it is important to provide extension and integration points, enabling complex functionality that goes beyond the scope of the core framework itself. In order to do this, PrettyFaces provides several extension points, described below:
It may sometimes be necessary to provide custom configuration
options in PrettyFaces. Loading URL-mappings from a database, for example, or generating
mappings based on the state of the file-system. Due to this requirement, PrettyFaces offers
an extension point for configuration providers to supply their own additional configuration
to be merged with the master configuration at the time when PrettyFaces boots up.
This is when you would implement a custom ConfigurationProvider
.
public class MyConfigurationProvider implements ConfigurationProvider { public PrettyConfig loadConfiguration(ServletContext servletContext) { // add new configuration elements here return new PrettyConfig(); } }
To let PrettyFaces know about your provider, you'll have to register your
implementation by creating a file named
META-INF/services/com.ocpsoft.pretty.faces.spi.ConfigurationProvider
in your classpath and add the fully-qualified class name of your implementation
class there.
META-INF/services/com.ocpsoft.pretty.faces.spi.ConfigurationProvider
com.example.MyConfigurationProvider
After all configurations have been loaded and merged from any built-in or registered
ConfigurationProvider sources, there is an
additional opportunity to post-process the entire configuration, for instance, if you
wanted to programmatically add security constraints to mappings based on various patterns.
This is when you would implement a custom ConfigurationPostProcessor
.
public class MyPostProcessor implements ConfigurationPostProcessor { public PrettyConfig processConfiguration(ServletContext servletContext, PrettyConfig config) { // make changes to the configuration here return config; } }
To let PrettyFaces know about your post-processor, you'll have to register your
implementation by creating a file named
META-INF/services/com.ocpsoft.pretty.faces.spi.ConfigurationPostProcessor
in your classpath and add the fully-qualified class name of your implementation
class there.
META-INF/services/com.ocpsoft.pretty.faces.spi.ConfigurationPostProcessor
com.example.MyPostProcessor
As part of the Annotations scanning
(one of PrettyFaces' configuration methods,) it may sometimes be necessary to integrate
with a custom bean-container that is not one of the built in containers supported natively.
It is in these cases when you should implement a custom ELBeanNameResolver. The following
example shows a resolver that will resolve the bean name by searching for a @Named
annotation.
public class MyBeanNameResolver implements ELBeanNameResolver { public boolean init(ServletContext servletContext, ClassLoader classLoader) { // tell PrettyFaces that initialization was successful return true; } public String getBeanName(Class<?> clazz) { // try to find @Named annotation Named annotation = clazz.getAnnotation(Named.class); // return name attribute if annotation has been found if(annotation != null) { return annotation.value(); } // we don't know the name return null; } }
To let PrettyFaces know about your resolver, you'll have to register your
implementation by creating a file named
META-INF/services/com.ocpsoft.pretty.faces.spi.ELBeanNameResolver
in your classpath and add the fully-qualified class name of your implementation
class there.
META-INF/services/com.ocpsoft.pretty.faces.spi.ELBeanNameResolver
com.example.MyBeanNameResolver
If PrettyFaces is executed in development mode, the configuration will be automatically reloaded
every few seconds. This allows the developer to modify the pretty-config.xml
and immediately test the changes without restarting the servlet container.
The DevelopmentModeDetector SPI allows the user to implement custom strategies to determine whether the application
is in development mode. The following class shows a simple detector which enables the development
mode if the system property devmode
is set to true
.
public class CustomDevelopmentModeDetector implements DevelopmentModeDetector { public int getPriority() { return 10; } public Boolean isDevelopmentMode(ServletContext servletContext) { return System.getProperty("devmode", "false").equals("true"); } }
You can give your own implementation a high precedence of the other implementations by giving it a very low priority.
To let PrettyFaces know about your custom detector, you'll have to register your
implementation by creating a file named
META-INF/services/com.ocpsoft.pretty.faces.spi.DevelopmentModeDetector
in your classpath and add the fully-qualified class name of your implementation
class there.
META-INF/services/com.ocpsoft.pretty.faces.spi.DevelopmentModeDetector
com.example.CustomDevelopmentModeDetector