Batalii z JAXB 2.1 ciąg dalszy 🙂

Po tym jak udało mi się zmusić XJC do wygenerowania schemy, dodania do wygenerowanego kodu @XmlJavaTypeAdapter i zamiany „w locie” atrybutu na kolekcje (opisane tutaj) pojawił sie mały problem. Po próbie dodania do <xjb:javaType /> silnie typizowanej kolekcji w następujący sposób:

<xjc:javaType name="java.util.Map&lt;String,String&gt;" adapter="com.nsn.tariffmig.parser.output.LliLibReferenceAdapter" />

<!-- tak tak pamietajcie, że to xml, więc > i < trzeba zapisywać jako encje -->


Pojawił się następujący problem w wygenerowanym kodzie:


import java.util.Map<String,String>;

Czyli nie całkiem to o co chodziło 🙁 Na szczęście źródła do JAXB są dostępne, więc postanowiłem sprawdzić ile zajmie znalezienie kodu, odpowiedzialnego za wypluwanie „import” cośtam. Okazało się to bajecznie proste, szybki grep:

grep -nirs 'import' *.java | less

Pojawiło się dość sporo wyników ale przecież import to słowo kluczowe w Javie. Z drugiej jednak strony nietrudno było odróżnić to czego szukałem, bo większość wpisów to prawdziwe importy, np:

com/sun/codemodel/JPackage.java:50:import java.util.Iterator;
com/sun/codemodel/JPackage.java:51:import java.util.List;
com/sun/codemodel/JPackage.java:52:import java.util.Map;

Natomiast ja szukałem tego:

com/sun/codemodel/JFormatter.java:110: importedClasses = new HashSet<JClass>();
com/sun/codemodel/JFormatter.java:266: * decide what types to import and what not to.
com/sun/codemodel/JFormatter.java:273: if(importedClasses.contains(type)) {

Teraz wystarczy tylko dodać „wymazywanie typu :D”, czyli zamienić linię 438 z:

p(„import”).p(clazz.fullName()).p(‚;’).nl();

na:

p(„import”).p(clazz.fullName().replaceAll(„<.*?>$”, „”)).p(‚;’).nl();

I już – kompilujemy, wkładamy to do jara (nie zapomnijcie o licencjach) i już możemy odpalać taska XJC z adapterami do silnie typizowanych kolekcji.

Prawda, że proste…