siebenschlaefer siebenschlaefer - 13 days ago 8
Java Question

Register different flows depending on Spring profile

in my application there are different spring profiles: development, test, ...

The question is, is there a way to register a flow depending on the activated spring profile?

For example I have the flows: aFlow.xml, bFlow.xml.

If spring profile development is activated, I want something like

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<webflow:flow-location path=".../aFlow.xml" />
</webflow:flow-registry>


and if spring profile test is activated, then I want something like

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<webflow:flow-location path=".../aFlow.xml" />
<webflow:flow-location path=".../bFlow.xml" />
</webflow:flow-registry>


Background: If the spring profile development is activated, the bFlow.xml may not be accessible. If the spring profile test is activated, the aFlow.xml and the bFlow.xml should be accessible.

Currently I have the following solution. I define

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
<webflow:flow-location path=".../aFlow.xml" />
</webflow:flow-registry>

<webflow:flow-registry id="flowRegistryTest" flow-builder-services="flowBuilderServices" parent="flowRegistry">
<webflow:flow-location path=".../bFlow.xml" />
</webflow:flow-registry>


and use different FlowHandlerMapping depending on the spring profile:

<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry"/>
<property name="defaultHandler">
<!-- If no flow match, map path to a view to render; e.g. the "/intro" path would map to the view named
"intro" -->
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
</property>
</bean>

<beans profile="test">
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping" primary="true">
<property name="flowRegistry" ref="flowRegistryTest"/>
<property name="defaultHandler">
<!-- If no flow match, map path to a view to render; e.g. the "/intro" path would map to the view named
"intro" -->
<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
</property>
</bean>
</beans>


Thanks in advance!

Answer

I found two solutions for my stated problem.

Assume the following initial situation: You have a spring profiles named test. You have a flow aFlow.xml and a flow bFlow.xml. You want to register aFlow no matter which profile is active and you want to register bFlow only if profile test is active.

The first solution uses a xml based configuration of the flow registry:

<beans profile="!test">
    <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
        <webflow:flow-location path=".../aFlow.xml"/>
    </webflow:flow-registry>
</beans>
<beans profile="test">
    <webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
        <webflow:flow-location path=".../aFlow.xml"/>
        <webflow:flow-location path=".../bFlow.xml"/>
    </webflow:flow-registry>
</beans>

The second solution uses a spring java based configuration of the flow registry:

@Configuration
public class FlowRegistryConfiguration extends AbstractFlowConfiguration {

    @Bean(name = "flowRegistry")
    public FlowDefinitionRegistry flowDefinitionRegistry() {

        FlowDefinitionRegistryBuilder builder = getFlowDefinitionRegistryBuilder(
            (FlowBuilderServices) getApplicationContext().getBean("flowBuilderServices"))
            .addFlowLocation(".../aFlow.xml");

        List<String> activeProfiles = Arrays.asList(getApplicationContext().getEnvironment().getActiveProfiles());

        if (activeProfiles.contains("test")) {
            builder = builder.addFlowLocation(".../bFlow.xml");
        }

        return builder.build();
    }
}

In my opinion the second solution is better because you do not use the same id at two different places.