Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

"nil" is not supported #414

Open
Kaiser1989 opened this issue Nov 14, 2019 · 8 comments
Open

"nil" is not supported #414

Kaiser1989 opened this issue Nov 14, 2019 · 8 comments

Comments

@Kaiser1989
Copy link

Kaiser1989 commented Nov 14, 2019

Seems that "nil" is not supported by ramltojaxrs:

Simple example:

Dog:
  type: object
  properties:
    bark: nil | boolean
    color: string

throws exception:
org.raml.ramltopojo.GenerationException: can't fetch type named nil | boolean

I'm using dependency
"org.raml.jaxrs:raml-to-jaxrs-gradle-plugin:3.0.6"

@jpbelang
Copy link
Contributor

Looking at it. Sort of remember fixing something like that.

@jpbelang
Copy link
Contributor

jpbelang commented Nov 18, 2019

Can you check this ?
https://repository-master.mulesoft.org/snapshots/org/raml/jaxrs/raml-to-jaxrs-gradle-plugin/3.0.8-SNAPSHOT ?

(We've been having problems with maven central and gradle).

@Kaiser1989
Copy link
Author

Kaiser1989 commented Nov 18, 2019

Thanks for your reply,

I tried your 3.0.8 SNAPSHOT, but still getting

Caused by: org.raml.ramltopojo.GenerationException: can't fetch type named nil | boolean

@jpbelang
Copy link
Contributor

jpbelang commented Nov 25, 2019

That's weird: I've got stuff generated appropriately (I think) in raml-for-jax-rs/raml-to-jaxrs/examples/maven-examples/type-torture-test/src/main/resources/world-music-api/api.raml

Can you share a pointer to your project of a bit of a larger sample ?

types:
  NilUnion:
    type: object
    properties:
      bark: nil | boolean
      color: string

Generating (and it's interface):

public class NilUnionImpl implements NilUnion {
  private NilUnion.BarkType bark;

  private String color;

  private Map<String, Object> additionalProperties = new ExcludingMap();

  public NilUnion.BarkType getBark() {
    return this.bark;
  }

  public void setBark(NilUnion.BarkType bark) {
    this.bark = bark;
  }

  public String getColor() {
    return this.color;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public Map<String, Object> getAdditionalProperties() {
    return additionalProperties;
  }

  public void setAdditionalProperties(String key, Object value) {
    this.additionalProperties.put(key, value);
  }

  @Override
  public boolean equals(Object o) {
    if (o == null) return false;
    if (this == o) return true;
    if (o instanceof NilUnion) return false;
    NilUnionImpl other = (NilUnionImpl) o;
    return java.util.Objects.equals(this.bark, other.bark) && java.util.Objects.equals(this.color, other.color) && java.util.Objects.equals(this.additionalProperties, other.additionalProperties);
  }

  @Override
  public int hashCode() {
    return Objects.hash(bark,color,additionalProperties);
  }

  public static class BarkTypeImpl implements NilUnion.BarkType {
    private Object anyType;

    public BarkTypeImpl() {
      this.anyType = null;
    }

    public BarkTypeImpl(Boolean nilBoolean) {
      this.anyType = nilBoolean;
    }

    public Object getNil() {
      if ( !(anyType == null)) throw new IllegalStateException("fetching wrong type out of the union: NullType should be null");
      return null;
    }

    public boolean isNil() {
      return anyType == null;
    }

    public Boolean getBoolean() {
      if ( !(anyType instanceof  Boolean)) throw new IllegalStateException("fetching wrong type out of the union: java.lang.Boolean");
      return (Boolean) anyType;
    }

    public boolean isBoolean() {
      return anyType instanceof Boolean;
    }

    @Override
    public boolean equals(Object o) {
      if (o == null) return false;
      if (this == o) return true;
      if (o instanceof NilUnion.BarkType) return false;
      BarkTypeImpl other = (BarkTypeImpl) o;
      return java.util.Objects.equals(this.anyType, other.anyType);
    }

    @Override
    public int hashCode() {
      return Objects.hash(anyType);
    }
  }
}

@Kaiser1989
Copy link
Author

Kaiser1989 commented Nov 25, 2019

Thanks for your interest. There is no need for a larger example:

I created a minimal example of the problem:
https://github.com/Kaiser1989/simpleRamlTest

I also found the evil guy, making it fail:
<generateTypesWith><value>jackson</value></generateTypesWith>
OR
<generateTypesWith><value>jackson2</value></generateTypesWith>

Jackson and Jackson2 let it fail. If i remove them, it's building fine.

Do you have any idea why this is not working with jackson?

@Kaiser1989
Copy link
Author

Kaiser1989 commented Nov 26, 2019

I finally found a workaround for this:
I don't use nil values anymore. I added a custom Plugin to provide java.util.Optional support:

With my OptionalPlugin:

...

@Override
public TypeName typeName(ReferencePluginContext referencePluginContext, TypeDeclaration ramlType, TypeName currentSuggestion) {	
    return ParameterizedTypeName.get(ClassName.get(Optional.class), currentSuggestion.box());
}

...

And then in my raml i use types annotation:

  DtoTest:
    type: object
    properties:
      foo:
        type: string
        (types):
          plugins:
            - name: pp.optionalType

Now i have a valid distinction between not exisiting, required but nullable, and normal values.

@jpbelang
Copy link
Contributor

That's awesome. I'll look into the original issue this week, and maybe try to integrate your Optional/Nil idea into normal spec parsing.

Thanks very much for your help....

@Kaiser1989
Copy link
Author

Thanks for your feedback. I like your project and will help whenever I can.

Of course it would be nice, if the "nil" stuff would work together with jackson. The annotation thing is just a functional workaround and makes the raml become implementation dependend.

It's working, but it's not specification compatible.

Best regards

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants