2012-02-21 7 views
10

Szukałem w Internecie z jakiegoś powodu, dlaczego JAXB generowane klasy mają chronionych członków (wszyscy, niezależnie od dziedziczenia).Dlaczego JAXB generuje klasy z chronionymi członkami i jak mogę to zmienić?

Chciałbym, aby członkowie byli prywatni.

Moje wyszukiwanie uszło pusto.

Mam normalne pliki xsd, które są konwertowane na klasy Java za pomocą Maven i JAXB. Najlepiej byłoby, gdyby wygenerowani członkowie byli prywatni, ale nie mogę znaleźć sposobu, aby to osiągnąć.

Czy istnieje sposób zmiany tego domyślnego zachowania?

+0

Wygenerowane przez JAXB klasy mają chronionych członków i być może generują je jako prywatne, i mówisz, że Idealnie wygenerowani członkowie powinni być prywatni, ale nie mogę znaleźć sposobu, aby to osiągnąć. Chcesz, aby wszyscy członkowie byli prywatni? Jak już mówisz, są one już prywatne, ale niektóre z nich są chronione, a następnie sprawdzają, czy klasy posiadające pola chronione są dziedziczone przez inne klasy, co może być przyczyną? – JMelnik

+0

@JMelnik: Sądzę, że jest to błąd w pisowni w pierwszym zdaniu. Po prostu sprawdziłem moje źródła i JAXB generuje wszystkie atrybuty członkowskie z modyfikatorem 'protected' (bez względu na dziedziczenie). Może PO może dostarczyć wyjaśnienia na temat pierwszego sentenence? – home

+0

Zmodyfikowaliśmy pierwsze zdanie. Wszyscy członkowie są "chronieni" (bez względu na dziedziczenie), ale chcę, żeby byli "prywatni". – tom

Odpowiedz

10

Cóż, zamierzam odpowiedzieć na moje własne pytanie. Tworzenie wtyczki było właściwą drogą.

Napisałem następującą wtyczkę i wygląda na to, że działa.

public class PrivateMemberPlugin 
    extends Plugin 
{ 

    @Override 
    public String getOptionName() 
    { 
     return "Xpm"; 
    } 

    @Override 
    public String getUsage() 
    { 
     return " -Xpm : Change members visibility to private"; 
    } 

    @Override 
    public boolean run(Outline model, Options opt, ErrorHandler errorHandler) 
     throws SAXException 
    { 
     for (ClassOutline co : model.getClasses()) 
     { 

      JDefinedClass jdc = co.implClass; 
      // avoid concurrent modification by copying the fields in a new list 
      List<JFieldVar> fields = new ArrayList<JFieldVar>(jdc.fields().values()); 
      for (JFieldVar field : fields) 
      { 
       // never do something with serialVersionUID if it exists. 
       if (!field.name().equalsIgnoreCase("serialVersionuid")) 
       { 
        // only try to change members that are not private 
        if (field.mods().getValue() != JMod.PRIVATE) 
        { 
         // since there is no way to change the visibilty, remove the field an recreate it 
         jdc.removeField(field); 
         jdc.field(JMod.PRIVATE, field.type(), field.name()); 

        } 
       } 
      } 

     } 
     return true; 
    } 

} 

Możesz go użyć, jeśli chcesz.

+0

Powinieneś edytować swoją odpowiedź za pomocą zdefiniowanej wtyczki, w ten sposób łatwiej będzie znaleźć rozwiązanie. Dobra robota! – JMelnik

+0

@Matthew, doceniam twoją odpowiedź do mojej odpowiedzi, ale nie sądzę, że jest to istotne. Ta wtyczka ma być używana podczas przechodzenia z kodu WSDL/XSD do Java. O ile mi wiadomo, nie ma takiego opisu adnotacji na żadnej z nich, stąd usunę twoją notatkę. – tom

+0

Nowsza wersja biblioteki Codemodel umożliwia aktualizację stanu obiektu JMods. W takim przypadku możesz wywołać 'JMods # setPrivate()'. – user1808924

6

Uważam, że jedynym sposobem, aby to osiągnąć, jest samodzielne opracowanie modelu JXC plugin, wyszukiwanie google dla próbek.

Co może zrobić plugin?

Wtyczka XJC uczestniczy w generowaniu kodu ze schematu. Może on zdefiniować własne modyfikacje, które użytkownicy mogą wykorzystać do sterowania nim, może uzyskać dostęp do kodu wygenerowanego przez JAXB RI, może wygenerować dodatkowych klas/metod/pól/adnotacji/komentarzy, a także może również wymienić niektóre z punkty plug-in w procesie kompilacji, takie jak nazwa XML -> konwersja nazw Java.

Na szczęście, właściciel pytania opracował i shared the plugin.

Powiązane problemy