Magic Bean: A very basic library which will generate POJOs.

Overview

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

  1. Boilerplate reduction for code that needs "dumb" POJOs
  2. Demonstrate that annotation processors and source code generation aren't that scary
  3. Cover some of the use cases of lombok without the compiler hacking it does

The non-goals of this library are

  1. To provide a tool which fits all use cases. (conflicts with goal #2)
  2. Provide a way to generate immutable value objects. Use records, immutables, or elbow grease for that.
  3. 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.

Comments
  • Publish to Maven Central

    Publish to Maven Central

    What we want is probably a github action that automatically publishes on a tagged release.

    (Some people just aren't comfortable with Jitpack for whatever reason)

    enhancement 
    opened by bowbahdoe 16
  • Add @Generated to generated code

    Add @Generated to generated code

    1. @javax.annotation.processing.Generated("dev.mccue.magicbean.processor.AnnotationProcessor") should be put above the generated interfaces and abstract classes
    2. The example code in the README should be updated to reflect this
    enhancement good first issue 
    opened by bowbahdoe 2
  • Code generated for equals, hashCode, toString handles the no fields case

    Code generated for equals, hashCode, toString handles the no fields case

    Added a solution to the following: https://github.com/bowbahdoe/magic-bean/issues/6 The code that's generated in equals, hashCode, toString delegates the call to the super class when there are no fields defined in the annotated bean. I did not find any unit tests in the project so I did not add a new dependency on a unit test framework (such as junit) therefore I tested the change manually. Let me know if you want unit tests in the project and I can add the dependency and corresponding tests.

    opened by cranberrycheeze 2
  • add gradle snippet to readme

    add gradle snippet to readme

    addresses #5

    This works for both the Groovy and Kotlin DSLs.

    The compileOnly configuration is needed to get access to the MagicBean annotation at compile time, while the annotationProcessor configuration informs the compiler to actually use the processor.

    opened by hepptho 1
  • Builders

    Builders

    Open question: Is it worth it to add builder generation? I don't want to put any significant validation or customization there, but for some of the potential audience of "people otherwise using lombok" it can be helpful.

    It could also be another library that reads off the same annotation defined here.

    (To be clear, the effort for any version of the feature is not the blocker)

    opened by bowbahdoe 1
  • Set up code style for the repo

    Set up code style for the repo

    This task would include

    1. Adding the necessary hooks to maven and documenting how to run an autoformat before commit
    2. Adding a check through github workflows that some style is followed
    3. Reformatting the code to fit whatever style guide

    I don't have any particular preference here, this would mostly be done for the sake of doing it

    enhancement help wanted good first issue 
    opened by bowbahdoe 1
  • Document and test usage with JPA/Hibernate

    Document and test usage with JPA/Hibernate

    One of the more common frameworks this tool would make sense for would be Hibernate.

    There is certain stuff that should be called out to not be done, like using generateEqualsAndHashCode=true

    help wanted good first issue 
    opened by bowbahdoe 1
  • Give a specific error if used on interfaces

    Give a specific error if used on interfaces

    From @Pante

    I don’t think this check is enough since TypeElement includes interfaces as well. Probably need to check the ElementKind. Also probably want to check that the class isn’t abstract as well. https://github.com/bowbahdoe/magic-bean/blob/main/src/main/java/dev/mccue/magicbean/processor/AnnotationProcessor.java#L132

    enhancement 
    opened by bowbahdoe 1
  • Only ever use abstract classes

    Only ever use abstract classes

    This is a breaking change, but it unfortunately makes sense to be compatible with existing frameworks which don't see the bean methods if they come from an interface.

    opened by bowbahdoe 0
  • Target the error from a private or final non static field to the field itself

    Target the error from a private or final non static field to the field itself

    From @Pante

    Imo, the message could be displayed on the individual fields rather than the class itself, https://github.com/bowbahdoe/magic-bean/blob/main/src/main/java/dev/mccue/magicbean/processor/AnnotationProcessor.java#L148

    enhancement good first issue 
    opened by bowbahdoe 0
  • Add basic unit test scaffolding

    Add basic unit test scaffolding

    This is for doing stuff like testing directly with bean frameworks like https://commons.apache.org/proper/commons-beanutils/, https://cocoon.apache.org/1.x/xsp.html, etc and not exactly the stuff needed for elementary/direct testing of the processor.

    @cranberrycheeze Do you still want to do the scaffolding for this?

    enhancement help wanted good first issue 
    opened by bowbahdoe 0
Releases(3.1.1)
Owner
Ethan McCue
Ethan McCue
This project shows how to configure basic auth to secure our rest API and basic transaction on Data JPA

Basic Atuthentication Spring Boot Data JPA, MySQL This project shows how to configure basic auth to secure our rest API and basic transaction on Data

Hafizullah Samim 1 Feb 10, 2022
A Minecraft plugin that adds magic spells for epic fights!

EpicSpellsPlugin EpicSpellsPlugin is a Minecraft Spigot plugin for version 1.18+ that aims to add magic spells to the game for epic pvp and pve fights

null 27 Dec 4, 2022
Library for converting from one Java class to a dissimilar Java class with similar names based on the Bean convention

Beanmapper Beanmapper is a Java library for mapping dissimilar Java classes with similar names. The use cases for Beanmapper are the following: mappin

null 26 Nov 15, 2022
Melnica Server is a custom basic Servlet Container application which depends on Socket Programming.

Melnica Server Melnica Server is a custom basic Servlet Container application which depends on Socket Programming. The Description of Project Melnica

Batuhan Düzgün 18 Jun 26, 2022
Spring Bean 容器创建

Spring手撸专栏:small-spring-step-01 作者: 小傅哥,Java Developer, ✏️ 虫洞 · 科技栈,博主, ?? 《重学Java设计模式》图书作者 本仓库以 Spring 源码学习为目的,通过手写简化版 Spring 框架,了解 Spring 核心原理。 在手写的

Spring 手撸专栏 13 Jul 18, 2021
SitemapGen4j is a library to generate XML sitemaps in Java.

sitemapgen4j SitemapGen4j is a library to generate XML sitemaps in Java. What's an XML sitemap? Quoting from sitemaps.org: Sitemaps are an easy way fo

Dan Fabulich 151 Dec 16, 2022
Library to generate images from layers

react-native-image-generator Library for generate images from other images Installation yarn add react-native-image-generator Usage import { generate

Evgeny Usov 13 Nov 16, 2022
this repo is probs gonna die cuz idk very much java but i will update it when i learn how to actually DO SHIT

pastegod.cc shitty rename of zihasz client base rn but as i learn java i will paste-i mean add modules ;) (23/9/2021) why is everyone starring and wat

null 9 Dec 9, 2022
GodType is a very simple Bukkit plugin to allow the console (or a player) to chat as a defined name.

GodType GodType is a very simple Bukkit plugin to allow the console (or a player) to chat as a defined name. Config A config.yml file will be created

null 1 Dec 24, 2021
Very spicy additions to the Java programming language.

Project Lombok Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another g

Project Lombok 11.7k Dec 30, 2022
Very briefly capturing some of new/ update in API that were introduced after Java 8 that may come handy for dev folks while programming

Very briefly capturing some of new/ update in API that were introduced after Java 8 that may come handy for dev folks while programming. Also have created tests demonstrating those APIs and playaround with it.

Jayaramanan Kumar 3 Jan 24, 2022
Conway's Game Of Life, but made by me in a very inefficient and unpractical way. Still, I am proud!

Conway's Game Of Life, but made by me in a very ugly and inefficient way. Still, I am proud! I want to share my appreciation to cellular automata with anyone who comes across this repo.

Ulaş Dilek 6 May 25, 2022
This is some Discord bot I made to help me learn Java. Not very useful yet.

JennyChan This is some Discord bot I made to help me learn Java. Not very useful yet. What it can do so far: Reply to mention List commands Show bot u

null 0 Sep 1, 2022
Java-Programs---For-Practice is one of the Java Programming Practice Series By Shaikh Minhaj ( minhaj-313 ). This Series will help you to level up your Programming Skills. This Java Programs are very much helpful for Beginners.

Java-Programs---For-Practice is one of the Java Programming Practice Series By Shaikh Minhaj ( minhaj-313 ). This Series will help you to level up your Programming Skills. This Java Programs are very much helpful for Beginners. If You Have any doubt or query you can ask me here or you can also ask me on My LinkedIn Profile

Shaikh Minhaj 3 Nov 8, 2022
This is simple project to show how to create a basic API using Java 11 + Maven + Spring Boot + PostgrSQL + Flyway.

This is simple project to show how to create a basic API using Java 11 + Maven + Spring Boot + PostgrSQL + Flyway.

Sean Maxwell 11 Dec 10, 2022
Basic crud operations with json data, main focus is with tests

Spring Crud operations Basic crud operations with json data, main focus is with tests. For future reference Road Map Basic Crud on controllers (done)

Jarno Saastamoinen 1 Feb 1, 2022
It contains a simple program to apply basic arithmetic operations in Morse code

Morse-Calculator By Mohamad Farag F. Makkawi This project falls under DSL (Domain Specific Language) . the Input is an equation in which simple arithm

Mohamad Makkawi 1 Apr 29, 2022
This repo holds all the basic code and documentation to the ev3 roboter of group 3 from WS21/22

e3base This repo holds all the basic code and documentation to the ev3 roboter of group 3 from WS21/22 Task Every group had to build a roboter using t

Jonas Deipenbrock 1 Feb 12, 2022
A basic shard that demonstrates optional implementations, and interfaces.

Glass - Example A basic shard that demonstrates optional implementations, and interfaces. Basic Information A lot of stuff will be more complex than o

null 1 Feb 13, 2022