Code Monkey home page Code Monkey logo

magic-bean's Introduction

Magic Bean

A very basic library which will generate getters and setters.

Requires Java 21+.

Maven

<dependency>
    <groupId>dev.mccue</groupId>
    <artifactId>magic-bean</artifactId>
    <version>2024.04.26</version>
    <scope>provided</scope>
</dependency>

Gradle

dependencies {
    compileOnly("dev.mccue:magic-bean:2024.04.26")
    annotationProcessor("dev.mccue:magic-bean:2024.04.26")
}

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.

Usage

Basic Example

I receive

import dev.mccue.magicbean.MagicBean;

import java.util.List;

@MagicBean
public final class Example extends ExampleBeanOps {
    int x;
    String name;
    List<String> strs;
}

You receive

sealed abstract class ExampleBeanOps extends java.lang.Object permits Example {

    private Example self() {
        return (switch (this) { case Example __ -> __; });
    }

    /**
     * Get the current value for x.
     */
    public int getX() {
        return self().x;
    }

    /**
     * Set the current value for x.
     */
    public void setX(int x) {
        self().x = x;
    }

    /**
     * Get the current value for name.
     */
    public java.lang.String getName() {
        return self().name;
    }

    /**
     * Set the current value for name.
     */
    public void setName(java.lang.String name) {
        self().name = name;
    }

    /**
     * Get the current value for strs.
     */
    public java.util.List<java.lang.String> getStrs() {
        return self().strs;
    }

    /**
     * Set the current value for strs.
     */
    public void setStrs(java.util.List<java.lang.String> strs) {
        self().strs = strs;
    }

}

Complete Example

I receive

import dev.mccue.magicbean.MagicBean;

import java.util.List;

@MagicBean(
        allArgsStaticFactory = true,
        equalsAndHashCode = true,
        toString_ = true
)
public final class Example extends ExampleBeanOps {
    int x;
    String name;
    List<String> strs;
}

You receive

sealed abstract class ExampleBeanOps extends java.lang.Object permits Example {

    private Example self() {
        return (switch (this) { case 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 self().x;
    }

    /**
     * Set the current value for x.
     */
    public void setX(int x) {
        self().x = x;
    }

    /**
     * Get the current value for name.
     */
    public java.lang.String getName() {
        return self().name;
    }

    /**
     * Set the current value for name.
     */
    public void setName(java.lang.String name) {
        self().name = name;
    }

    /**
     * Get the current value for strs.
     */
    public java.util.List<java.lang.String> getStrs() {
        return self().strs;
    }

    /**
     * Set the current value for strs.
     */
    public void setStrs(java.util.List<java.lang.String> strs) {
        self().strs = strs;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || !(o instanceof Example other)) {
            return false;
        }
        else {
            return java.util.Objects.equals(self().x, other.x) &&
                   java.util.Objects.equals(self().name, other.name) &&
                   java.util.Objects.equals(self().strs, other.strs);
        }
    }

    @Override
    public int hashCode() {
        return java.util.Objects.hash(
                self().x,
                self().name,
                self().strs
        );
    }

    @Override
    public String toString() {
        return "Example[" + "x=" + self().x +
               ", " + "name=" + self().name +
               ", " + "strs=" + self().strs + "]";
    }

}

Usage with frameworks

Customizing

This library is just about 350 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.

magic-bean's People

Contributors

bowbahdoe avatar cranberrycheeze avatar hepptho avatar sentryman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

magic-bean's Issues

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)

Logo

Submissions open for anyone artistically inclined to make a logo for the project.

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

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)

Use "o" as a bean property

Edge case: If someone uses o as a property name this has a conflict with the generated code. This should be easy enough to fix, just need to add either detection or a more wild property name like o$.

No current code should be affected by this since it is impossible to make happen and still compile ATM and I also have heard no reports..

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

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.