wnameless / apt-constant-generator

Annotation Processing Tool for Java Constant generating

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Maven Central

apt-constant-generator

Annotation Processing Tool for Java Constant generating.

Goal - generating classes of Constants based on Java class names

Java Constants(public static final) are widely used during development, however they are lack of flexibility. This apt-constant-generator provides a workaround toward this common issue.

Purpose - easier refactoring and maintenance by utilizing Java Constants

For example, Java annotation only accepts Constant or literal for String. Even though the annotation value may relate to class name somehow, we can't assign Class#getSimpleName or Class#getName to an annotation String attribute which makes refactoring and maintenance difficult sometimes.

Furthermore - optional Constants by annotation driven configuration

Constants such as String, primitive, Class and Enum can also be generated by annotation driven configuration and stored in the same generated class.

Maven Repo

<dependency>
	<groupId>com.github.wnameless.apt</groupId>
	<artifactId>apt-constant-generator</artifactId>
	<version>${newestVersion}</version>
	<!-- Newest version shows in the maven-central badge above -->
</dependency>

DEMO

Traditional approach:

@RequestMapping("/bars")
@Controller
public class BarController {}
// Spring Controller for Bar entity

Solution brought by apt-constant-generator:

// NRBar is a class of constants, which is automatically generated by spring-boot-up-apt
@RequestMapping(NRBar.RESOURCE_PATH)
@Controller
public class BarController {}
@NamedResource
public class Bar {}

Quick Start

Annotate @NamedResource with any class, enum or interface

@NamedResource
public class Bar {}

Maven dependencies

<dependency>
  <groupId>com.github.wnameless.apt</groupId>
  <artifactId>apt-constant-generator</artifactId>
  <version>${newestVersion}</version>
</dependency>

Maven plugins

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <annotationProcessorPaths>
      <path>
        <groupId>com.github.wnameless.apt</groupId>
        <artifactId>apt-constant-generator</artifactId>
        <version>${newestVersion}</version>
      </path>
    </annotationProcessorPaths>
  </configuration>
</plugin>

Feature List

Name option Description Since
NamedResource Generate a class of constants based on the annotated class name v1.0.0
default Default behavior of @NamedResource v1.0.0
injectable Add jakarta.inject.Named or javax.inject.Named to the generated class v1.0.0
markerInterface Option to implement marker interface INamedResource for the generated class v1.0.0
classNamePrefix
classNameSuffix
Add prefix or suffix to the generated class name v1.0.0
singular Change singular name for the annotated class v1.0.0
plural Change plural name for the annotated class v1.0.0
inferredConstants Infer other String constants by given naming formats v1.0.0
literalSingularConstants Create constants of literal singular names in different naming formats v1.0.0
literalPluralConstants Create constants of literal plural names in different naming formats v1.0.0
constants Add optional String constants v1.0.0
primitiveConstants Add optional primitive constants v1.0.0
classConstants Add optional Class constants v1.0.0
enumConstants Add optional Enum constants v1.0.0

πŸ” NamedResource

πŸ” Annotation option: default

Config:

@NamedResource
public SimpleNamedResource {}

Generated: NRSimpleNamedResource (NR is the default class name prefix)

NRSimpleNamedResource.SINGULAR // SimpleNamedResource
NRSimpleNamedResource.PLURAL   // SimpleNamedResources

NRSimpleNamedResource.CLASS_SIMPLE_NAME // SimpleNamedResource
NRSimpleNamedResource.CLASS_NAME        // model.SimpleNamedResource
NRSimpleNamedResource.PACKAGE_NAME      // model

// 5 naming formats: UPPER_CAMEL, LOWER_CAMEL, UPPER_UNDERSCORE, LOWER_UNDERSCORE, LOWER_HYPHEN
NRSimpleNamedResource.UPPER_CAMEL_SINGULAR      // SimpleNamedResource
NRSimpleNamedResource.LOWER_CAMEL_SINGULAR      // simpleNamedResource
NRSimpleNamedResource.UPPER_UNDERSCORE_SINGULAR // SIMPLE_NAMED_RESOURCE
NRSimpleNamedResource.LOWER_UNDERSCORE_SINGULAR // simple_named_resource
NRSimpleNamedResource.LOWER_HYPHEN_SINGULAR     // simple-named-resource
NRSimpleNamedResource.UPPER_CAMEL_PLURAL        // SimpleNamedResources
NRSimpleNamedResource.LOWER_CAMEL_PLURAL        // simpleNamedResources
NRSimpleNamedResource.UPPER_UNDERSCORE_PLURAL   // SIMPLE_NAMED_RESOURCES
NRSimpleNamedResource.LOWER_UNDERSCORE_PLURAL   // simple_named_resources
NRSimpleNamedResource.LOWER_HYPHEN_PLURAL       // simple-named-resources

// Default inferred constants: RESOURCE, RESOURCES, RESOURCE_PATH
NRSimpleNamedResource.RESOURCE      // simple-named-resource
NRSimpleNamedResource.RESOURCES     // simple-named-resources
NRSimpleNamedResource.RESOURCE_PATH // /simple-named-resources

πŸ” Annotation option: injectable

Config:

// Default value is InjectType.NONE
@NamedResource(injectable = InjectType.JAKARTA) // InjectType.JAVAX is available
public class JakartaNamedResource {}

Generated:

@Named // jakarta.inject.Named
public final class NRJakartaNamedResource implements INamedResource {
  ...
}

πŸ” Annotation option: markerInterface

Config:

@NamedResource(markerInterface = false) // Default value is true
public class NoMarkerNamedResource {}

Generated:

public final class NRJakartaNamedResource { // By default, all generated classes implement INamedResource marker interface
  ...
}

πŸ” Annotation option: classNamePrefix and classNameSuffix

Config:

@NamedResource(classNamePrefix = "A", classNameSuffix = "Z")
public class PrefixSuffixNamedResource {}

Generated:

public final class APrefixSuffixNamedResourceZ implements INamedResource {
  ...
}

πŸ” Annotation option: singular

Config:

@NamedResource(singular = @Naming(value = "alt-sing-name-rsc", format = NamingFormat.LOWER_HYPHEN))
public class AlteredSingularNamedResource {}

Generated:

// JUnit
assertEquals("alt-sing-name-rsc", NRAlteredSingularNamedResource.SINGULAR);
// singular opt affects plural opt,
// however plural opt can be overridden if both singular and plural opts are existed
assertEquals("alt-sing-name-rscs", NRAlteredSingularNamedResource.PLURAL);

πŸ” Annotation option: plural

Config:

@NamedResource(plural = @Naming(value = "alt-pl-name-rscs", format = NamingFormat.LOWER_HYPHEN))
public class AlteredPluralOnlyNamedResource {}

Generated:

// JUnit
// plural opt won't affect singlur opt
assertEquals("AlteredPluralOnlyNamedResource", NRAlteredPluralOnlyNamedResource.SINGULAR);
assertEquals("alt-pl-name-rscs", NRAlteredPluralOnlyNamedResource.PLURAL);

πŸ” Annotation option: inferredConstants

Config:

@NamedResource(inferredConstants = {
    @InferredConstant(name = "ROOT", plural = true,
        format = NamingFormat.UPPER_CAMEL, prefix = "/"),
    @InferredConstant(name = "LIST_ITEM_TEMPLATE", plural = false,
        format = NamingFormat.LOWER_UNDERSCORE, suffix = "_{}")})
public class InferredConstantsNamedResource {}

Generated:

// JUnit
assertEquals("/InferredConstantsNamedResources", NRInferredConstantsNamedResource.ROOT);
assertEquals("inferred_constants_named_resource_{}", NRInferredConstantsNamedResource.LIST_ITEM_TEMPLATE);

πŸ” Annotation option: literalSingularConstants

Config:

@NamedResource(singular = @Naming(value = "MountEverest", format = NamingFormat.UPPER_CAMEL),
    literalSingularConstants = {
        NamingFormat.LOWER_CAMEL, NamingFormat.UPPER_CAMEL,
        NamingFormat.LOWER_UNDERSCORE, NamingFormat.UPPER_UNDERSCORE
    })

Generated:

// JUnit
assertEquals("mountEverest", NRLiteralSingularNamedResource.mountEverest);
assertEquals("mount_everest", NRLiteralSingularNamedResource.mount_everest);
assertEquals("MountEverest", NRLiteralSingularNamedResource.MountEverest);
assertEquals("MOUNT_EVEREST", NRLiteralSingularNamedResource.MOUNT_EVEREST);

πŸ” Annotation option: literalPluralConstants

Config:

@NamedResource(plural = @Naming(value = "bellBottoms", format = NamingFormat.LOWER_CAMEL),
    literalPluralConstants = {
        NamingFormat.LOWER_CAMEL, NamingFormat.UPPER_CAMEL,
        NamingFormat.LOWER_UNDERSCORE, NamingFormat.UPPER_UNDERSCORE
    })

Generated:

// JUnit
assertEquals("bellBottoms", NRLiteralPluralNamedResource.bellBottoms);
assertEquals("BellBottoms", NRLiteralPluralNamedResource.BellBottoms);
assertEquals("bell_bottoms", NRLiteralPluralNamedResource.bell_bottoms);
assertEquals("BELL_BOTTOMS", NRLiteralPluralNamedResource.BELL_BOTTOMS);

πŸ” Annotation option: constants

Config:

@NamedResource(constants = {
    @Constant(name = "DEATH_CARD", value = "Spade-1"),
    @Constant(name = "BEER_CARD", value = "Diamond-7")})
public class ConstantNamedResource {}

Generated:

// JUnit
assertEquals("Spade-1", NRConstantNamedResource.DEATH_CARD);
assertEquals("Diamond-7", NRConstantNamedResource.BEER_CARD);

πŸ” Annotation option: primitive constants

Config:

@NamedResource(
    booleanConstants = {@BooleanConstant(name = "LIE", value = false)},
    byteConstants = {@ByteConstant(name = "BITS", value = 8)},
    charConstants = {@CharConstant(name = "YES", value = 'y')},
    shortConstants = {@ShortConstant(name = "UNIX_EPOCH_YEAR", value = 1970)},
    intConstants = {@IntConstant(name = "MARS_DISTANCE_KM", value = 225000000)},
    longConstants = {@LongConstant(name = "LIGHT_YEAR_M", value = 9460730777119564L)},
    floatConstants = {@FloatConstant(name = "GOLDEN_RATIO", value = 1.618f)},
    doubleConstants = {@DoubleConstant(name = "PI", value = 3.14159265358979323846)}
)
public class ConstantsNamedResource {}

Generated:

// JUnit
assertEquals(false, NRConstantsNamedResource.LIE);
assertEquals(8, NRConstantsNamedResource.BITS);
assertEquals('y', NRConstantsNamedResource.YES);
assertEquals(1970, NRConstantsNamedResource.UNIX_EPOCH_YEAR);
assertEquals(225000000, NRConstantsNamedResource.MARS_DISTANCE_KM);
assertEquals(9460730777119564L, NRConstantsNamedResource.LIGHT_YEAR_M);
assertEquals(1.618f, NRConstantsNamedResource.GOLDEN_RATIO);
assertEquals(3.14159265358979323846, NRConstantsNamedResource.PI);

πŸ” Annotation option: classConstants

Config:

@NamedResource(
    classConstants = {@ClassConstant(name = "INTEGER_CLASS", value = Integer.class)}
)
public class ConstantsNamedResource {}

Generated:

// JUnit
assertEquals(Integer.class, NRConstantsNamedResource.INTEGER_CLASS);

πŸ” Annotation option: enumConstants

Config:

@NamedResource(
    enumConstants = {
        @EnumConstant(name = "MONTH_SEPTEMBER", valueType = Month.class, valueKey = "SEPTEMBER")}
)
public class ConstantsNamedResource {}

Generated:

// JUnit
assertEquals(Month.SEPTEMBER, NRConstantsNamedResource.MONTH_SEPTEMBER);

Advanced Usage:

// Lombok(@FieldNameConstants) - generates String constants for all Enum constant names
@FieldNameConstants
public enum RBG {
  @FieldNameConstants.Include RED,
  @FieldNameConstants.Include BLUE,
  @FieldNameConstants.Include GREEN;
}
// To avoid refactoring errors in the future by using RBG.Fields.BLUE as the valueKey
@NamedResource(
    enumConstants = {
        @EnumConstant(name = "RGB_BLUE", valueType = RBG.class, valueKey = RBG.Fields.BLUE)}
)
public class ConstantsNamedResource {}

MISC

Note Since
Java 17 required. v1.0.0

About

Annotation Processing Tool for Java Constant generating

License:Apache License 2.0


Languages

Language:Java 100.0%