Tuesday 19 April 2016

ocpsoft Rewrite

What is Rewrite? The answer is http://www.ocpsoft.org/rewrite/ :). There is a problem when you want to add rules at runtime without restarting web container. There isn't documentation for doing that. Here is the extension to official documentation ;).

When you want to add rule at runtime you have to implement your own HttpConfigurationCacheProvider.
public class ServletContextConfigurationCacheProvider extends HttpConfigurationCacheProvider
{
 /**
  * 
  */
 static Logger logger = Logger.getLogger(ServletContextConfigurationCacheProvider.class);
 /**
  * 
  */
 private static final String KEY = ServletContextConfigurationCacheProvider.class.getName() + "_cachedConfig";
 /**
  * 
  */
 private static final String RELOAD_CONFIGURATION = "org.ocpsoft.rewrite.config.CONFIG_RELOADING";

 /* (non-Javadoc)
  * @see org.ocpsoft.rewrite.spi.ConfigurationCacheProvider#getConfiguration(java.lang.Object)
  */
 @Override
 public Configuration getConfiguration(ServletContext context)
 {
  logger.debug("getConfiguration called");
  
  if(RewriteManager.isInitialized)
  {
   logger.debug("Configuration should not be reloaded");
   return (Configuration)context.getAttribute(KEY);
  }
  
  String reload = context.getInitParameter(RELOAD_CONFIGURATION);
  
  if (reload != null && "true".equalsIgnoreCase(reload.trim())) 
  {
   return null;
  }
  
  return (Configuration) context.getAttribute(KEY);
   }

   /* (non-Javadoc)
    * @see org.ocpsoft.rewrite.spi.ConfigurationCacheProvider#setConfiguration(java.lang.Object, org.ocpsoft.rewrite.config.Configuration)
    */
 @Override
   public void setConfiguration(ServletContext context, Configuration configuration)
   {
    logger.debug("setConfiguration called");
       context.setAttribute(KEY, configuration);
   }

   /* (non-Javadoc)
    * @see org.ocpsoft.common.pattern.Weighted#priority()
    */
 @Override
   public int priority()
   {
      return -10000;
   }
}

getConfiguration(ServletContext context) is called when reqeust occurs. When you want to reload rules you have to set  RewriteManager.isInitialized to false. The next step is to register service. In order to do that create file: org.ocpsoft.rewrite.spi.ConfigurationCacheProvider and place it in: WEB-INF/classes/META-INF/services catalog of your application. File should contain one line of code: aik.cms.navigation.configuration.ServletContextConfigurationCacheProvider.

Next step is to set contex parameter in web.xml, just add this code:


 
     org.ocpsoft.rewrite.config.CONFIG_RELOADING
     true
  
Of course you have to implement HttpConfigurationProvider to load configuration. The last step is to set variable to prevent reloading configuration for each request. You have to do it inside getConfiguration() method after return configuration. In should look like this:
@RewriteConfiguration
public class AikCmsRewriteConfigurationProvider extends HttpConfigurationProvider implements Serializable
{
 /**
  * Serial version UID
  */
 private static final long serialVersionUID = 5515384196041689598L;
 /**
  * Logger object
  */
 static Logger logger = Logger.getLogger(AikCmsRewriteConfigurationProvider.class);
 /**
  * 
  */
 @ManagedProperty(value="#{userBean}")
 protected UserBean userBean;
 
 /* (non-Javadoc)
  * @see org.ocpsoft.rewrite.config.ConfigurationProvider#getConfiguration(java.lang.Object)
  */
 @Override
 public Configuration getConfiguration(ServletContext servletContext)
 {
               ConfigurationBuilder config = ConfigurationBuilder.begin();
              // Here build your rules


  RewriteManager.getInstance().isInitialized = true; // This variable is read in  ServletContextConfigurationCacheProvider and prevents to calling this method each request

  return config;
 }
 /* (non-Javadoc)
  * @see org.ocpsoft.common.pattern.Weighted#priority()
  */
 @Override
 public int priority()
 {
  // TODO Auto-generated method stub
  return 1;
 }
}

No comments:

Post a Comment