How to negate a property in pom.xml?

Apart from profile activation, Maven doesn't have a boolean logic implemented. So if want to negate a property to pass it to a plugin, you'll need to do it yourself. It is a bit clumsy, but you could use the build-helper-maven-plugin:bsh-property goal, which enables to write a BeanShell script and export variables defined in it as Maven properties:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <version>1.12</version>
  <executions>
    <execution>
      <id>negate-prop</id>
      <phase>initialize</phase>
      <goals>
        <goal>bsh-property</goal>
      </goals>
      <configuration>
        <source>dontDoSomething = !${doSomething};</source>
        <properties>
          <property>dontDoSomething</property>
        </properties>
      </configuration>
    </execution>
  </executions>
</plugin>

You can't override the property, but you can define a new one containing the result of the negation; in the example above, it is dontDoSomething. This is ran in the initialize phase so that the rest of the plugins can use it as a parameter, with the standard ${dontDoSomething}.

This could be enhanced to have a default value for dontDoSomething if doSomething doesn't exist.

<source>
  value = project.getProperties().getProperty("doSomething");
  dontDoSomething = value == null ? false : !Boolean.parseBoolean(value);
</source>

BeanShell is a scripting language that looks very much like Java and you can use existing Java methods. In the above, the property "doSomething" is retrieved from the project's properties (project is injected by the plugin at evaluation-time with the current Maven project); it it isn't defined, we return false, otherwise, we negate the value.


If doSomething is specifically a system property, it could also be possible to (ab)use the profile activation feature and have 2 profiles: one activated by a property being true and setting another to false, and a second profile doing the inverse:

<profiles>
  <profile>
    <id>pro-1</id>
    <activation>
      <property>
        <name>doSomething</name>
        <value>!false</value>
      </property>
    </activation>
    <properties>
      <dontDoSomething>false</dontDoSomething>
    </properties>
  </profile>
  <profile>
    <id>pro-2</id>
    <activation>
      <property>
        <name>doSomething</name>
        <value>false</value>
      </property>
    </activation>
    <properties>
      <dontDoSomething>true</dontDoSomething>
    </properties>
  </profile>
</profiles>

This won't work if doSomething is a Maven property set in the <properties> tag for example. It will need to be passed as a system property with mvn -DdoSomething=true|false. The corresponding profile will be activated according to the value of the system property, which will define the dontDoSomething property to its inverse. If the property isn't defined, pro-1 will be active, setting dontDoSomething to the default value of false. All of this is quite ugly though...


I don't know the exact answer but I think you could try the following to invert the properties value (from http://maven.apache.org/guides/introduction/introduction-to-profiles.html). Declare another property where you invert the value of the first property:

<property>
    <name>dontDoSomething</name>
    <value>!${doSomething}</value>
</property>

Tags:

Maven