ashishgupta_mca
ashishgupta_mca

Reputation: 578

Spring expression to evaluate OS

I want to evaluate the OS (operating system) system property to load the environment corresponding configuration file. E.g. if OS evaluates to Windows, the properties-win.xml will be loaded or if OS evaluates to Unix or Linux, the properties-unix.xml will be loaded.

The below spel works fine

#{(systemProperties['os.name'].indexOf('nix') >= 0 or systemProperties['os.name'].indexOf('nux') >= 0 or systemProperties['os.name'].indexOf('aix') > 0 ) ? 'linux' : 
        ((systemProperties['os.name'].indexOf('Win') >= 0) ? 'windows' : 'Unknow OS')}

But in place of evaluating the systemProperties['os.name'] each time, I want to have this in a variable and then wants to match the condition. I saw the #this variable usage (http://docs.spring.io/spring-framework/docs/3.0.6.RELEASE/spring-framework-reference/html/expressions.html sec 6.5.10.1) and tried to make the below spel

#{systemProperties['os.name'].?((#this.indexOf('nix') >= 0 or #this.indexOf('nux') >= 0 or #this.indexOf('aix') > 0 ) ? 'unix' : 
    (#this.indexOf('win') >= 0) ? 'windows' : 'Unknown')}

But somehow, it's giving parsing exception.

Does anyone can suggest anything?

Upvotes: 4

Views: 2822

Answers (3)

rafaelnaskar
rafaelnaskar

Reputation: 783

For future searchs, follows the other alternative:

root:
  pathLinux: ${ROOT_PATH_LINUX:/mnt/data/}
  pathWindows: ${ROOT_PATH_WINDOWS:F:/data/}
  path: "${ROOT_PATH:#{systemProperties['os.name'].toLowerCase().contains(\"windows\") ? \"${root.pathWindows}\" : \"${root.pathLinux}\" }}"

In case, it's possible overrides the configuration using the ROOT_PATH environment variable yet, or ROOT_PATH_LINUX, or ROOT_PATH_WINDOWS, OS specific vars.

Upvotes: 0

Uwe Allner
Uwe Allner

Reputation: 3467

It is not possible to set a variable within a Spel expression. Variables have to be set to the context. You could do as

context.setVariable("os", SystemProperties.getProperty("os.name")); 

and then use it in your Spel as #os

Upvotes: 2

Andrei Stefan
Andrei Stefan

Reputation: 52368

How about this approach, a more elegant one, I would say. Requires Spring 4.

public class WindowsEnvironmentCondition implements Condition {
     public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata) {
          return context.getEnvironment().getProperty("os.name").indexOf("Win") >= 0;
     }
}

public class LinuxEnvironmentCondition implements Condition {
     public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata) {
          return (context.getEnvironment().getProperty("os.name").indexOf("nux") >= 0 
                 || context.getEnvironment().getProperty("os.name").indexOf("aix") >= 0);
     }
}

And then you can use the Conditions above to annotate the desired methods or classes to be loaded depending on the environment:

@Configuration
@Conditional(LinuxEnvironmentCondition.class)
@ImportResource("classpath:/META-INF/spring/linux.xml")
public class LinuxConfig {

private @Value("${test}") String message;

public @Bean
ExampleService service() {
    ExampleService service = new ExampleService();
    service.setMessage(message);
    return service;
}
}

@Configuration
@Conditional(WindowsEnvironmentCondition.class)
@ImportResource("classpath:/META-INF/spring/windows.xml")
public class WindowsConfig {

private @Value("${test}") String message;

public @Bean
ExampleService service() {
    ExampleService service = new ExampleService();
    service.setMessage(message);
    return service;
}
}

linux.xml:

<context:property-placeholder location="classpath:/META-INF/spring/linux.properties" />

windows.xml:

<context:property-placeholder location="classpath:/META-INF/spring/windows.properties" />

Maybe it can be enhanced more, but just wanted to show you another idea of using certain xml files depending on the OS.

Upvotes: 8

Related Questions