3

i am using jaxb to generate code from an xsd.

The generated code contains a lot of annotations; for classes and fields.

I am trying to use com.sun.tools.internal.xjc.Plugin to modify the generated code.

In the plugin run() method we are given an Outline class from which we can get ClassOutline. ClassOutline has an JDefinedClass final member which has the info about actual class which will be generated.

If i want to add anything, there are apis in JDefinedClass which can be used. But if i want to remove something, there is no way.

e.g. i cannot clear annotations, because the JDefinedClass.annotations() method returns an UnmodifiableCollection. so i cannot clear it or remove anything from it.

i tried to create another JDefinedClass by invoking the _class method but the ClassOutline.implClass variable is final, so i cannot set it.

how to get a JDefinedClass which does not have any annotations?

is there another phase of code generation which i can trap into to really control the generation of JDefinedClass?

weima
  • 4,653
  • 6
  • 34
  • 55
  • Short answer: you'll need to remove things from the model, not from the code model. Long answer follows. – lexicore Sep 21 '15 at 03:41
  • i see there is a `postProcessModel` method, with `Model` as input. i am seeing how can this `Model` can be manipulated to remove annotations – weima Sep 21 '15 at 09:25
  • i see that `BeanGenerator` does not do any checks before invoking `implClass.annotate2`. there is no way to stop its invocations – weima Sep 21 '15 at 10:01
  • i finally did it. removed each `JDefinedClass` from the `_package`. added new `JDefinedClass` with the same name, and copied `implements`, `extends`, `fileds`, `methods`, `javadoc` etc from original `JDefinedClass`. a bit tedious but couldn't find anything else to do. – weima Sep 21 '15 at 16:00

2 Answers2

1

The code model is, indeed mostly "write only". But, speaking of annotations, you have probably missed the methods like com.sun.codemodel.JDefinedClass.removeAnnotation(JAnnotationUse) and com.sun.codemodel.JMethod.removeAnnotation(JAnnotationUse) (implemented from com.sun.codemodel.JAnnotatable.removeAnnotation(JAnnotationUse)).

So they're there. You can remove annotations with the normal CodeModel API.

As I can see, you can also remove fields and methods from classes. So what exactly are you missing?

lexicore
  • 42,748
  • 17
  • 132
  • 221
  • actually in my `jdk1.7.0_55\lib\tools.jar` , the `JDefinedClass` and `JMethod` does not have any method called `removeAnnotation`. yes, there is a `removeField` in `JDefinedClass` – weima Sep 22 '15 at 11:58
  • @weima Don't use JDK-internal XJC. I checked some more-or-less actual JAXB RI. – lexicore Sep 22 '15 at 13:09
  • you mean i should install jaxb-ri and use its xjc. which is the distribution which provided JAXB RI implementation? can you suggest. i could not find any jaxb-ri impl which even contains `JDefinedClass`. i saw `com.sun.xml.bind » jaxb-impl` – weima Sep 22 '15 at 14:08
  • also my boss tells me not to use vendor specific apis. isnt `com.sun.tools.internal.xjc.Plugin` vendor specific? i could not find any other `Plugin` class – weima Sep 22 '15 at 14:10
  • using jaxb-ri from here instead "https://jaxb.java.net/downloads/ri/" version 2.2.11\ – weima Sep 22 '15 at 14:51
  • Just use the right dependencies. See this QA, for instance: http://stackoverflow.com/questions/26413431/which-artifacts-should-i-use-for-jaxb-ri-in-my-maven-project It does not matter, where you get them. I'm using Maven and get dependencies from the central Maven repository which also contains JAXB RI: http://repo1.maven.org/maven2/org/glassfish/jaxb/ – lexicore Sep 22 '15 at 14:58
  • Well, XJC plugin **is** vendor specific. So, take it or leave it, there is nothing to discuss. – lexicore Sep 22 '15 at 14:59
  • this version has `jDefinedClass.removeAnnotation(JAnnotationUse)` – weima Sep 22 '15 at 15:18
0

JDefinedClass.annotations() It return an unmodifiable collection object and you cannot modify them.

So work around for this, you can restrict annotation addition/deletion at class and field level before building JCodeModel.

You need to create a custom Jackson2Annotator class which extends Jackson2Annotator and override their methods according to your requirement.

Following are few methods which are being used for specific type of annotation property:

  1. propertyOrder(OTB JsonPropertyOrder)
  2. propertyInclusion(OTB JsonInclude)
  3. propertyField(can be used for custom defined annotation at field level)

More you can discover by looking Jackson2Annotator class what fit into your need.