Magic Bean
A very basic library which will generate POJOs.
Requires Java 17+.
Maven
<repositories>
<repository>
<id>jitpack.ioid>
<url>https://jitpack.iourl>
repository>
repositories>
<dependency>
<groupId>dev.mccuegroupId>
<artifactId>magic-beanartifactId>
<version>2.0.2version>
<scope>providedscope>
dependency>
deps.edn
{:mvn/repos {"jitpack" {:url "https://jitpack.io"}}
:aliases {:compile {:deps {dev.mccue/magic-bean {:mvn/version "2.0.2"}}}}}
What this does
This uses an annotation processor to generate a class which can be extended to automatically derive the boilerplate code for
- getters and setters
- equals and hashCode
- toString
- an all argument constructor
The primary goals of this library are
- Boilerplate reduction for code that needs "dumb" POJOs
- Demonstrate that annotation processors and source code generation aren't that scary
- Cover some of the use cases of lombok without the compiler hacking it does
The non-goals of this library are
- To provide a tool which fits all use cases. (conflicts with goal #2)
- Provide a way to generate immutable value objects. Use records, immutables, or elbow grease for that.
- Support old Java versions.
PRs welcome for
- carrying over annotations to generated get and set methods.
Usage
Basic Example
I receive
import dev.mccue.magicbean.MagicBean;
@MagicBean
public final class Example implements ExampleBeanOps {
int x;
String name;
List<String> strs;
}
You receive
sealed interface ExampleBeanOps permits Example {
/**
* Get the current value for x.
*/
default int getX() {
return ((Example) this).x;
}
/**
* Set the current value for x.
*/
default void setX(int x) {
((Example) this).x = x;
}
/**
* Get the current value for name.
*/
default java.lang.String getName() {
return ((Example) this).name;
}
/**
* Set the current value for name.
*/
default void setName(java.lang.String name) {
((Example) this).name = name;
}
/**
* Get the current value for strs.
*/
default java.util.List<java.lang.String> getStrs() {
return ((Example) this).strs;
}
/**
* Set the current value for strs.
*/
default void setStrs(java.util.List<java.lang.String> strs) {
((Example) this).strs = strs;
}
}
Complete Example
I receive
import dev.mccue.magicbean.MagicBean;
// If you want equals/hashCode, toString, or a static factory
// then an abstract class will be generated, not an interface.
@MagicBean(
generateAllArgsStaticFactory = true,
generateEqualsAndHashCode = true,
generateToString = true
)
public final class Example extends ExampleBeanOps {
int x;
String name;
List<String> strs;
}
You receive
sealed abstract class ExampleBeanOps permits Example {
/**
* Creates an instance of Example.
*/
public static Example of(
int x,
java.lang.String name,
java.util.List<java.lang.String> strs
) {
var o = new Example();
o.setX(x);
o.setName(name);
o.setStrs(strs);
return o;
}
/**
* Get the current value for x.
*/
public int getX() {
return ((Example) this).x;
}
/**
* Set the current value for x.
*/
public void setX(int x) {
((Example) this).x = x;
}
/**
* Get the current value for name.
*/
public java.lang.String getName() {
return ((Example) this).name;
}
/**
* Set the current value for name.
*/
public void setName(java.lang.String name) {
((Example) this).name = name;
}
/**
* Get the current value for strs.
*/
public java.util.List<java.lang.String> getStrs() {
return ((Example) this).strs;
}
/**
* Set the current value for strs.
*/
public void setStrs(java.util.List<java.lang.String> strs) {
((Example) this).strs = strs;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
else if (!(o instanceof Example other)) {
return false;
}
else {
return java.util.Objects.equals(((Example) this).x, other.x) &&
java.util.Objects.equals(((Example) this).name, other.name) &&
java.util.Objects.equals(((Example) this).strs, other.strs);
}
}
@Override
public int hashCode() {
return java.util.Objects.hash(
((Example) this).x,
((Example) this).name,
((Example) this).strs
);
}
@Override
public String toString() {
return "Example[" + "x=" + ((Example) this).x +
", " + "name=" + ((Example) this).name +
", " + "strs=" + ((Example) this).strs + "]";
}
}
Customizing
This library is just over 300 lines of Java contained within a single file. If it doesn't do exactly what you want, feel free to make a PR or fork and make your own edits.