Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring expression to evaluate OS

Tags:

spring

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?

like image 504
ashishgupta_mca Avatar asked Jan 11 '23 17:01

ashishgupta_mca


2 Answers

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.

like image 195
Andrei Stefan Avatar answered Jan 13 '23 05:01

Andrei Stefan


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

like image 25
Uwe Allner Avatar answered Jan 13 '23 05:01

Uwe Allner