Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for generic type arguments to javaType #151

Closed
stackmagic opened this issue Feb 13, 2014 · 13 comments
Closed

Add support for generic type arguments to javaType #151

stackmagic opened this issue Feb 13, 2014 · 13 comments
Milestone

Comments

@stackmagic
Copy link

I'm trying to generate a Map field and it seems this is possible but not quite the way I want it.

AdditionalProperties could generate a Map[String, MyType] which is exactly what I'd want, the problem is the map field is not supposed to be named "additionalProperties" and I haven't found a way to rename additionalProperties (plus you can only have one of those).

The second thing I tried is to use javaType. That creates a map alright but the parametrization is missing, it's just "Map". Adding the generics to the javaType causes an error.

Neither solution is fully satisfactory. For now, I'll just stick to the plain map because I don't want the field-naming of my internal and external data models to drift apart. Since this is a message I'll only serialize, never de-serialize I can simply assign the map to be serialized and it'll work just fine but I still think it's a hack and a proper solution with generics would be nice.

edit: make generics args visible, github swallows lower-than and greater-than signs

@joelittlejohn
Copy link
Owner

The point of this library is to support databinding to Java types, creating maps to represent json objects isn't really within the scope of this library. You may find it easier to use a library like Jackson directly in this case.

Alternatively, you could create a wrapper type for each map you need, and for those maps use the additionalProperties rule to constrain the values. Imagine you have an object and you require three properties a, b and c, where the value of each is a map:

foo.json:

{"a" : {...},
 "b" : {...},
 "c" : {...}}

Now I can create four types: Foo.java, A.java, B.java, C.java.

A, B and C don't declare any properties, they simply use additionalProperties to hold values. This isn't the most elegant if you want to hold maps and not bind to Java types, but it would work.

@stackmagic
Copy link
Author

We use this to define a contract between a java server and javascript client so we're bound to what jsonschema can model and what js2p can generate. If I knew the names of the individual properties I'd model them directly but since they're unknown beforehand we need to use a generic data container (map) for this.

Thanks for your suggestions anyway.

@joelittlejohn
Copy link
Owner

Are the properties on these unknown objects constrained to a specific type? I mean, if you were able to supply generic type arguments, what would you supply?

@stackmagic
Copy link
Author

Yes. I would make it a Map[String, Double] for this case.

Currently it all seems to work out since the Java Model contains a parametrised map with which we work internally. To serialize to the js client, it is assigned to the generated plain Map and all is fine. To deserialize (which we do not currently do), we'd just have to have some extra type checking/mapping in the object translator before assigning to the internal model. So using javaType=java.util.Map isn't such a big nuisance after all.

@joelittlejohn
Copy link
Owner

Hmm, I don't think it would be too difficult to support a syntax like

"javaType" : "java.util.Map<String,Double>"

I'm going to do some hacking and see what I come up with. The type arguments wouldn't be validated in any way by jsonschema2pojo but if you provide valid class names I don't see why this shouldn't work.

@stackmagic
Copy link
Author

That sounds great!

@joelittlejohn
Copy link
Owner

I've pushed a change and built a snapshot that's available here:

http://oss.sonatype.org/content/repositories/snapshots/org/jsonschema2pojo/

Could you build the current master or use this snapshot and let me know if this works for you?

@stackmagic
Copy link
Author

Perfect! Thanks a lot! 👍

@joelittlejohn joelittlejohn added this to the 0.4.1 milestone Feb 21, 2014
@joelittlejohn
Copy link
Owner

@stackmagic have you had a chance to try this?

@stackmagic
Copy link
Author

Yes I tested it right away and like I said it works perfectly :) Sorry if that wasn't clear from my last message.

I hope you're going to keep this new feature?

@joelittlejohn
Copy link
Owner

Ah, I see, thanks!

Yes, I'll definitely keep this feature. It'll be released in 0.4.1.

@brentryan
Copy link

@joelittlejohn Have you or anyone tried adding support for something similar to this, but where the actual object type you're generating supports generics? So my schema would look like this:

{
    "type": "object",
    "javaType": "MyGeneric<T>",
    "properties": {
        "fields": {
            "type": "array",
            "items": {
                "javaType": "T"
            }
        }
    }
}

And this would generate a class like:

public class MyGeneric<T> {
 ....
}

@joelittlejohn
Copy link
Owner

Not a simple thing to implement :) I'd be a little concerned we're getting to the point where we're really just writing Java in a more terse syntax. Scala or Groovy might be a better option at this point.

So no I haven't tried this and I haven't seen any fork that attempts this.

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

No branches or pull requests

3 participants