Skip to content

A Gradle plugin that generates a Java source file with constants for keys in properties files.

License

Notifications You must be signed in to change notification settings

cthing/gradle-property-key-constants

Repository files navigation

C Thing Software gradle-property-key-constants

CI Portal

A Gradle plugin that generates a Java source file with constants for keys in properties files.

Features

  • Processes multiple properties files
  • Provides control over generated source file layout (e.g. wrap constants in inner classes)
  • Can generate constants as either public or package private fields
  • Automatically adds generated source files to source sets

Motivation

A common pattern in Java applications is to extract strings and numeric values from the application source code and place them in a properties file. Each value in the properties file has a key which is used in the application to obtain the value. A common use of this pattern is providing localized strings to an application. A properties file is created for each translation of the application strings. The set of keys in each file is the same, thereby allowing the application to refer to the strings using the same key regardless of the currently selected language.

The property keys are strings and applications typically hardcode those strings wherever they need to obtain a property value. Unfortunately, this can lead to problems due to misspelling of keys, and can make renaming of keys a challenge because it is a string replacement. To address these issues, the org.cthing.property-key-constants plugin extracts the key names from properties files and generates a source file containing constants whose values are the key names. This means that property values can be obtained using the constants rather than hardcoded strings. This avoids misspelling and makes renaming a straightforward refactoring operation.

Usage

The plugin is available from the Gradle Plugin Portal and can be applied to a Gradle project using the plugins block:

plugins {
  id("org.cthing.property-key-constants") version "1.0.0"
}

Specifying Properties Files

Applying the plugin creates the propertyKeyConstants extension, and the generatePropertyKeyConstants and generateTestPropertyKeyConstants tasks. The following example demonstrates how to generate a constants file from properties files. The example uses the following two properties files:

src/main/resources/prop1.properties

key1=Hello World
key2=Goodbye World

src/main/resources/prop2.properties

abc.def.17=Yes
uvw.xyz.18=No

To generate a constants file containing the property keys, configure the generatePropertyKeyConstants task:

plugins {
    java
    id("org.cthing.property-key-constants") version "1.0.0"
}

tasks {
    generatePropertyKeyConstants {
        classname = "org.cthing.test.MyConstants"
        source(file("src/main/resources/prop1.properties"), file("src/main/resources/prop2.properties"))
    }
}

This will generate the source file build/generated-src/property-key-constants/main/org/cthing/test/MyConstants.java. The file will contain string constants for each property key. The constants are wrapped in a nested class for each property file.

//
// DO NOT EDIT - File generated by the org.cthing.property-key-constants Gradle plugin.
//

package org.cthing.test;

/**
 * Constants for property keys in:
 * <ul>
 *   <li>prop1.properties</li>
 *   <li>prop2.properties</li>
 * </ul>
 */
@SuppressWarnings("all")
public final class Constants {

    public static final class Prop1 {
        public static final String KEY1 = "key1";
        public static final String KEY2 = "key2";

        private Prop1() { }
    }

    public static final class Prop2 {
        public static final String ABC_DEF_17 = "abc.def.17";
        public static final String UVW_XYZ_18 = "uvw.xyz.18";

        private Prop2() { }
    }

    private Constants() { }
}

To generate a constants file for property files used in testing, configure the generateTestPropertyKeyConstants task in a similar manner as above.

The generated source file is automatically included in the compile source set, so it will be compiled and included in the application.

Both the generatePropertyKeyConstants and generateTestPropertyKeyConstants tasks are instances of the org.cthing.gradle.plugins.properties.PropertyKeyConstantsTask class, which is derived from the Gradle SourceTask. Therefore, the properties files can be specified using any of the methods provided by that task (e.g. source, include).

Generated Source File Layout

By default, the generated constants are wrapped in an inner class for each property file. The plugin provides a number of other layouts for the constants. A layout is selected globally by configuring the propertyKeyConstants extension or per task by configuring the generatePropertyKeyConstants or generateTestPropertyKeyConstants task.

Nested Classes

Wraps the constants in an inner class for each property file. This is the default source layout so no configuration is needed. The above example shows the source code resulting from this layout.

Flat With Prefix

The key constants for each property file are defined directly in the generated class. The constants are all prefixed with the name of the property file in uppercase. The following globally selects this layout:

import org.cthing.gradle.plugins.properties.SourceLayout

...

propertyKeyConstants {
    sourceLayout = SourceLayout.FLAT_WITH_PREFIX
}

...

or per task:

import org.cthing.gradle.plugins.properties.SourceLayout

...

tasks {
    generatePropertyKeyConstants {
        ...
        sourceLayout = SourceLayout.FLAT_WITHOUT_PREFIX
    }
}

For the above example properties files, the following Java source file is generated:

//
// DO NOT EDIT - File generated by the org.cthing.property-key-constants Gradle plugin.
//

package org.cthing.test;

/**
 * Constants for property keys in:
 * <ul>
 *   <li>prop1.properties</li>
 *   <li>prop2.properties</li>
 * </ul>
 */
@SuppressWarnings("all")
public final class Constants {

    public static final String PROP1_KEY1 = "key1";
    public static final String PROP1_KEY2 = "key2";

    public static final String PROP2_ABC_DEF_17 = "abc.def.17";
    public static final String PROP2_UVW_XYZ_18 = "uvw.xyz.18";

    private Constants() { }
}

Flat Without Prefix

The key constants for each property file are defined directly in the generated class with no property file prefix. This is a convenient layout when one property file is specified. If multiple property files are specified, the generated constant names may collide.

import org.cthing.gradle.plugins.properties.SourceLayout

...

propertyKeyConstants {
    sourceLayout = SourceLayout.FLAT_WITHOUT_PREFIX
}

...

For the above example properties files, the following Java source file is generated:

//
// DO NOT EDIT - File generated by the org.cthing.property-key-constants Gradle plugin.
//

package org.cthing.test;

/**
 * Constants for property keys in:
 * <ul>
 *   <li>prop1.properties</li>
 *   <li>prop2.properties</li>
 * </ul>
 */
@SuppressWarnings("all")
public final class Constants {

    public static final String KEY1 = "key1";
    public static final String KEY2 = "key2";

    public static final String ABC_DEF_17 = "abc.def.17";
    public static final String UVW_XYZ_18 = "uvw.xyz.18";

    private Constants() { }
}

Constants Access Modifier

By default, the generated constants and classes are given public access. The plugin can be configured to generate the constants and classes with package private access. Global configuration:

import org.cthing.gradle.plugins.properties.SourceAccess

...

propertyKeyConstants {
    sourceAccess = SourceAccess.PACKAGE
}

...

or per task configuration:

import org.cthing.gradle.plugins.properties.SourceAccess

...

tasks {
    generatePropertyKeyConstants {
        ...
        sourceAccess = SourceAccess.PACKAGE
    }
}

Output Directory

The default location for the generated constants source file is:

${project.layout.buildDirectory}/generated-src/property-key-constants/${sourceSet.name}`

To change the location, configure the outputDirectory property on the generatePropertyKeyConstants or generateTestPropertyKeyConstants tasks.

Compatibility

The following Gradle and Java versions are supported:

Plugin Version Gradle Version Minimum Java Version
1.0.0+ 8.2+ 17

Building

The plugin is compiled for Java 17. If a Java 17 toolchain is not available, one will be downloaded.

Gradle is used to build the plugin:

./gradlew build

The Javadoc for the plugin can be generated by running:

./gradlew javadoc

Releasing

This project is released on the Gradle Plugin Portal. Perform the following steps to create a release.

  • Commit all changes for the release
  • In the build.gradle.kts file, edit the ProjectVersion object
    • Set the version for the release. The project follows semantic versioning.
    • Set the build type to BuildType.release
  • Commit the changes
  • Wait until CI successfully builds the release candidate
  • Verify GitHub Actions build is successful
  • In a browser go to the C Thing Software Jenkins CI page
  • Run the "gradle-property-key-constants-validate" job
  • Wait until that job successfully completes
  • Run the "gradle-property-key-constants-release" job to release the plugin to the Gradle Plugin Portal
  • Wait for the plugin to be reviewed and made available by the Gradle team
  • In a browser, go to the project on GitHub
  • Generate a release with the tag <version>
  • In the build.gradle.kts file, edit the ProjectVersion object
    • Increment the version patch number
    • Set the build type to BuildType.snapshot
  • Update the CHANGELOG.md with the changes in the release and prepare for next release changes
  • Update the Usage and Compatibility sections in the README.md with the latest artifact release version
  • Commit these changes