Oh, oh, qualcuno è interessato agli interni XJC. Potrei essere di aiuto dato che probabilmente ho sviluppato più plugin JAXB di chiunque altro (vedi JAXB2 Basics per esempio)
Ok, iniziamo. Nel XJC il compilatore schema non seguendo approssimativamente
- analizza lo schema
- crea il modello dello schema (CClass, CPropertyInfo ecc)
- crea il contorno (ClassOutline, FieldOutline ecc)
- Renders il codice del modello (JClass, JDefinedClass, JMethod ecc)
- Scrive il codice fisico (file ex.Java sul disco)
Iniziamo con gli ultimi due.
I file Java non necessitano di una spiegazione, spero.
Il modello di codice è anche una cosa relativamente facile. È un'API che può essere utilizzata per costruire codice Java a livello di codice. Potresti semplicemente usare la concatinazione delle stringhe, ma è molto più soggetta a errori. Con CodeModel hai quasi la certezza di ottenere almeno il codice Java corretto grammaticamente. Quindi spero che anche questa parte sia chiara. (A proposito, mi piace molto CodeModel. Ho recentemente scritto JavaScript Code Model sulla base di idee dal CodeModel.)
Osserviamo ora il "modello" e il "contorno". Il modello è il risultato dell'analisi dello schema in entrata. Modella i costrutti dello schema entrante, principalmente in termini di "classi" che corrispondono a tipi complessi e "proprietà" che corrispondono a elementi, attributi e valori (es.quando hai un tipo complesso con un contenuto semplice).
Il modello deve essere interpretato come un costrutto di modellazione logica vicino a XML e schema. In quanto tale, descrive solo i tipi e le proprietà che hanno. È sicuramente molto più complesso di come lo sto descrivendo, ci sono tutti i tipi di eccezioni e caveat - a partire dai tipi di wilcard (xsd: any), gruppi di sostituzione, enumerazioni, tipi built-in e così via.
Abbastanza interessante, un fratello di è RuntimeTypeInfoSetImpl
utilizzato da JAXB nel runtime. Quindi è anche un tipo di modello, che tuttavia non viene analizzato dallo schema XML ma piuttosto dalle annotazioni JAXB nelle classi. Il concetto è lo stesso. Entrambi i modelli e RuntimeTypeInfoSetImpl
implementano l'interfaccia TypeInfoSet
che è un super-costrutto. Controlla interfacce come ClassInfo
e PropertyInfo
- hanno implementazione sia per la fase di compilazione (CClassInfo
e CPropertyInfo
in XJC) che di esecuzione (RuntimeClassInfoImpl
ecc. Per JAXB RI).
Ok, quindi, quando XJC ha analizzato e analizzato lo schema, hai il Model
. Questo non può ancora produrre il codice. Esistono, infatti, diverse strategie per produrre il codice. È possibile generare solo classi annotate o generare un'interfaccia/implementazione di coppie di classi come in JAXB 1. L'intera generazione di codice non è in realtà il compito del modello. Inoltre, esiste una serie di aspetti rilevanti per la natura fisica del codice Java, ma non rilevanti per il modello. Ad esempio, devi raggruppare le classi in pacchetti. Questo è guidato dal sistema di impacchettamento di Java, non dalle proprietà del modello stesso.
E qui entrano in gioco i contorni. È possibile visualizzare i contorni come passaggio tra il modello dello schema e il modello di codice. È possibile visualizzare i contorni come fabbriche per gli elementi del modello di codice responsabili dell'organizzazione del codice e della generazione di JDefinedClass
es da CClassInfo
s.
Quindi hai ragione, è davvero molto complicato. Non sono un dipendente Sun/Oracle, non l'ho progettato (conosco la persona che lo ha fatto, però e lo rispetto molto). Posso immaginare un paio di motivi per alcune decisioni di progettazione, per esempio: modelli
- utilizzare la stessa interfaccia per la fase di compilazione e di run-time
- Consentire diverse strategie di generazione di codice
- accettano plugin per manipolare il modello creato
Sono d'accordo che questo progetto è molto complicato, ma ha le sue ragioni. Una prova è che è stato effettivamente possibile creare un generatore di mapping per i mapping XML-to-JavaScript, in pratica sugli stessi modelli. Ho appena dovuto sostituire la generazione del codice lasciando intatta l'analisi dello schema. (Vedi Jsonix per quello.)
Ok, spero di far luce sul motivo per cui le cose in XJC sono come sono. Buona fortuna con queste API, non sono straghtforward. Sentiti libero di controllare il codice open source esistente, ci sono molti esempi disponibili.
ps. Volevo davvero sempre scrivere questo. :)
In effetti, ottima spiegazione. Il motivo per cui lo chiedo è perché sto migliorando il ['jaxb-xew-plugin'] (https://github.com/dmak/jaxb-xew-plugin/blob/master/src/main/java/com/sun /tools/xjc/addon/xew/XmlElementWrapperPlugin.java), e l'intero algoritmo è un po 'incasinato perché alcune informazioni sono nel modello di struttura e altre nel modello di codice. Forse puoi rispondere alla mia piccola domanda: è possibile imparare che la proprietà data è stata personalizzata ('fieldOutline.getPropertyInfo(). GetCustomizations()' è sempre vuoto)? E in generale, qual è il posto migliore per discutere di questi trucchi? Grazie. –
hi @lexicore, ho aggiunto una domanda, http://stackoverflow.com/questions/32677605/jaxb-how-to-remove-anything-from-jdefinedclass puoi darci un'occhiata. – weima
hai accennato che consente "Consenti strategie diverse di generazione del codice". Quali sono le strategie che possono essere seguite – weima