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

Support Java annotations in JSON Schema #107

Closed
joelittlejohn opened this issue Jun 23, 2013 · 4 comments
Closed

Support Java annotations in JSON Schema #107

joelittlejohn opened this issue Jun 23, 2013 · 4 comments

Comments

@joelittlejohn
Copy link
Owner

Original author: [email protected] (June 14, 2013 09:19:50)

Option to specify any java annotations on class and property level that will be added to the java source file.

Example:

{
"type" : "object",
"annotations" : [
"@entity",
"@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")"
],
//...
}

Yes, you can change the source file manually but that would be annoying if you use as example the maven plugin.

Original issue: http://code.google.com/p/jsonschema2pojo/issues/detail?id=107

@joelittlejohn
Copy link
Owner Author

From [email protected] on June 19, 2013 21:15:37
Thanks for raising this Joos. It certainly sounds like a useful addition.

Unfortunately however, I don't think it's possible to implement this in the way you have proposed. Firstly, when you provide a code-snippet like that, there's no way for jsonschema2pojo to decide what imports would be required in order to embed that code, and the result would be types that do not compile. I guess we could replace your code with fully qualified type names like:

"annotations" : [
    "@javax.persistence.Entity",
    "@com.fasterxml.jackson.annotation.JsonIdentityInfo(generator=com.fasterxml.jackson.annotation.ObjectIdGenerators.IntSequenceGenerator.class, property="@id")"      
]

Secondly (and more importantly) it's not actually possible using CodeModel to supply a direct code snippet (as a string) to as a type or field level annotation. There is very limited support for such direct snippets in CodeModel.

One limited way in which this could be supported is as follows:

"annotations" : [
    "javax.persistence.Entity",
    "java.lang.Deprecated"
]

In other words, as long as the annotation you want to use does not require any arguments to be supplied then it can be added.

@joelittlejohn
Copy link
Owner Author

From [email protected] on June 19, 2013 21:16:42
I'd probably call this 'javaAnnotations' too, to match the other existing (and proposed) extension properties :)

@joelittlejohn
Copy link
Owner Author

From [email protected] (@keinerj) on July 1, 2013 09:14

I have now looked at CodeModel and used it a bit and I understand now that my suggestion won't work. However being able to supply arguments to custom annotations would be important. Else I think it will not help that much.

What about:

"annotations" : [
        {
            "class" : "javax.persistence.Entity",
        },
        {
            "class" : "javax.persistence.Table",
            "name" : "myEntity"
        }        
    ]

However I see now an additional problem, namely when the arguments value is a class as in

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")

This sure is pretty hard to do in a generalized fashion.

For my case I just created a second json file for the annotations and read that in separately into my app and adjust the code model generated by jsonschema2pojo.

I solved the problem with the class values by Class.forName("com.foo.Bar") and in case that class does not exist (ClassNotFoundException) I generated a dummy class at runtime with this exact fully qualified name using javaassist.

It's a bit hacky but work sin my case:

public Class<?> getClass(String fullQualifiedClassName)
        throws CannotCompileException {

    try {
        Class<?> clazz= Class.forName(fullQualifiedClassName);
        return clazz;
    } catch (ClassNotFoundException ex) {
        logger.warn("Class {} not loaded. Generating dummy class.", fullQualifiedClassName);
        return generateDummyClass(fullQualifiedClassName);
    }
}

private Class<?> generateDummyClass(String fullQualifedClassName)
        throws CannotCompileException {

    ClassPool pool = ClassPool.getDefault();
    pool.insertClassPath(new ClassClassPath(this.getClass()));
    CtClass ctClass = pool.makeClass(fullQualifedClassName);
    Class<?> clazz = ctClass.toClass();
    return clazz;
}

@joelittlejohn
Copy link
Owner Author

Thanks for the code examples. I think we're going down a problematic path here which would ultimately lead us to replicating a lot of Java's value syntax into the 'javaAnnotations' object. A usable implementation would also be required to support both type-level and field-level annotations IMO and I don't see this as feasible. If you do think you have a neat solution to generalizing this then feel free to submit a PR.

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

1 participant