HST orderable Valve support
Custom valves can be injected into an existing pipeline with control where it should be injected. Before, a custom valve could only be appended (as in added after the last one) to either
- initialization valves
- processing valves
- cleanup valves
It was for example not possible to inject a custom valve into an existing HST pipeline somewhere in the middle of, say the processing valves. We have added more support for this now by having the possibility to have your custom valve extend from HST API org.hippoecm.hst.container.valves.AbstractOrderableValve. If your valve extends from AbstractOrderableValve, you can use in the Spring bean definition for your valve the properties beforeValves and afterValves, through which you can specify where in the existing pipeline your valve should be injected. If it should be possible for other valves to position themselves relative to your custom valve, you should also specify in the Spring bean definition for your valve a valveName.
The beforeValves and afterValves can be a comma separated list of valves that should be before/after your valve. Typically, you specify a single valve in beforeValves/ afterValves. The valveName is in general as a best practice equal to the Spring bean id (if you do not have an id just use a logical name, like camelcase classname). Thus for example if you have your CustomValve, the Spring bean configuration could look like:
<bean id="myCustomValve" class="org.example.container.MyCustomValve"> <property name="valveName" value="myCustomValve" /> <property name="afterValves" value="securityValve, subjectBasedSessionValve"/> <property name="beforeValves" value="pageCachingValve"/> </bean>
A worked out example
Assume you have a custom processing valve, myCustomValve that must be executed in the existing HST DefaultSitePipeline in the processing valves somewhere after the securityValve but before the pageCachingValve. You can achieve this as follows:
Make sure your valve extends from AbstractOrderableValve
For example
import org.hippoecm.hst.container.valves.AbstractOrderableValve; import org.hippoecm.hst.core.container.ValveContext; public class MyCustomValve extends AbstractOrderableValve { @Override public void invoke(ValveContext context) throws ContainerException { try { // do your thing } finally { context.invokeNext(); } } }
Make sure your Spring bean configuration uses beforeValves and afterValves.
<bean id="myCustomValve" class="org.example.container.MyCustomValve" > <property name="valveName" value="myCustomValve" /> <property name="afterValves" value="securityValve"/> <property name="beforeValves" value="pageCachingValve"/> </bean>
Inject your custom bean into the existing HST DefaultSitePipeline in the right order in the processing valves:
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject"> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="org.hippoecm.hst.core.container.Pipelines" /> <property name="targetMethod" value="getPipeline"/> <property name="arguments"> <value>DefaultSitePipeline</value> </property> </bean> </property> <property name="targetMethod" value="addProcessingValve"/> <property name="arguments"> <ref bean="myCustomValve" /> </property> </bean>