Skip to content

Request Helidon Builder to allow adding annotations at builder level #10811

@klustria

Description

@klustria

Helidon Version: 4.2.x and higher

Enhancement Description

Looking for Helidon Builder to replace Lombok for generating builders. For example, a Lombok annotated code like:

   @Value
    @JsonDeserialize(builder = DemoWorkflowArguments.Builder.class)
    @Builder(builderClassName = "Builder")
    public static class DemoWorkflowArguments implements Loggable {

        @JsonProperty
        long size;
        @JsonProperty
        boolean encrypted;
        @JsonProperty
        int workflowId;

        @Override
        @JsonIgnore
        public Map<String, String> getDecorations() {
            HashMap<String, String> decorations = new HashMap<>();
            decorations.put(DefaultLogAndMetricsDecorator.CORRELATION_ID, "DemoWorkflowCorrelationId");
            return decorations;
        }

        @JsonPOJOBuilder(withPrefix = "")
        public static class Builder {
        }
    }

will generate this:

    @JsonDeserialize(
        builder = Builder.class
    )
    public static final class DemoWorkflowArguments implements Loggable {
        @JsonProperty
        private final long size;
        @JsonProperty
        private final boolean encrypted;
        @JsonProperty
        private final int workflowId;

        @JsonIgnore
        public Map<String, String> getDecorations() {
            HashMap<String, String> decorations = new HashMap();
            decorations.put("correlationId", "DemoWorkflowCorrelationId");
            return decorations;
        }

        @Generated
        DemoWorkflowArguments(long size, boolean encrypted, int workflowId) {
            this.size = size;
            this.encrypted = encrypted;
            this.workflowId = workflowId;
        }

        @Generated
        public static Builder builder() {
            return new Builder();
        }

        @Generated
        public long getSize() {
            return this.size;
        }

        @Generated
        public boolean isEncrypted() {
            return this.encrypted;
        }

        @Generated
        public int getWorkflowId() {
            return this.workflowId;
        }

        @Generated
        public boolean equals(Object o) {
            if (o == this) {
                return true;
            } else if (!(o instanceof DemoWorkflowArguments)) {
                return false;
            } else {
                DemoWorkflowArguments other = (DemoWorkflowArguments)o;
                if (this.getSize() != other.getSize()) {
                    return false;
                } else if (this.isEncrypted() != other.isEncrypted()) {
                    return false;
                } else {
                    return this.getWorkflowId() == other.getWorkflowId();
                }
            }
        }

        @Generated
        public int hashCode() {
            int PRIME = true;
            int result = 1;
            long $size = this.getSize();
            result = result * 59 + (int)($size >>> 32 ^ $size);
            result = result * 59 + (this.isEncrypted() ? 79 : 97);
            result = result * 59 + this.getWorkflowId();
            return result;
        }

        @Generated
        public String toString() {
            long var10000 = this.getSize();
            return "DemoWorkflow.DemoWorkflowArguments(size=" + var10000 + ", encrypted=" + this.isEncrypted() + ", workflowId=" + this.getWorkflowId() + ")";
        }

        @JsonPOJOBuilder(
            withPrefix = ""
        )
        public static class Builder {
            @Generated
            private long size;
            @Generated
            private boolean encrypted;
            @Generated
            private int workflowId;

            @Generated
            Builder() {
            }

            @JsonProperty
            @Generated
            public Builder size(long size) {
                this.size = size;
                return this;
            }

            @JsonProperty
            @Generated
            public Builder encrypted(boolean encrypted) {
                this.encrypted = encrypted;
                return this;
            }

            @JsonProperty
            @Generated
            public Builder workflowId(int workflowId) {
                this.workflowId = workflowId;
                return this;
            }

            @Generated
            public DemoWorkflowArguments build() {
                return new DemoWorkflowArguments(this.size, this.encrypted, this.workflowId);
            }

            @Generated
            public String toString() {
                return "DemoWorkflow.DemoWorkflowArguments.Builder(size=" + this.size + ", encrypted=" + this.encrypted + ", workflowId=" + this.workflowId + ")";
            }
        }
    }

Helidon Builder can do the following to emulate above result:

  • Can switch to "java bean" style (io.helidon.builder.api.Prototype.Blueprint#beanStyle) to create getters and setters.
  • Can add implementation of an interface (like implements Loggable above) and creates a default method on the interface to implement methods that need to be overriden.

Helidon is unable to:

  • We do not have an ability to add annotations to builder. So this would work with serializing into JSON (using defaults for everything), but not for deserialization.

Metadata

Metadata

Assignees

Labels

4.xVersion 4.xP2builderRelated to the builder supportenhancementNew feature or request

Type

Projects

Status

Sprint Scope

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions