giovedì 26 giugno 2008

Castor: un framework esagggerato per oggettizzare l'XML


Warning! Questo post è ad altissimo contenuto di geekiness. Se non sei un nerd di quelli veramente feroci, scappa finché sei in tempo: qui trovi sicuro modi migliori di passare il tempo.

Ora che ho allontanato un buon 90% dei possibili lettori, posso introdurre l'argomento del giorno: oggi parliamo di Castor, un framework open-source per la gestione in java di dati strutturati in maniera non-object-oriented.

Dato che il mondo pullula di framework con lo stesso scopo (addirittura credo che uno sia stato integrato nel jdk ufficiale, a partire da java 6), anziché stare a spiegare perché ho deciso di dedicare un post proprio a Castor faccio prima a raccontare come l'ho usato.

Scopo del gioco: caricare un file xml piuttosto complesso, validarlo rispetto a uno schema xsd e usare i dati in esso contenuti come configurazione per un altro pezzo di software.

Detta così pare veramente una cazzata, se non fosse che il file xml "piuttosto complesso" è roba di 6-7 livelli di tag annidati, ciascuno coi suoi attributi e contenuti: usare direttamente il DOM e imballare il codice di getElementsByTagName(), getChildren() e simili in casi complessi come questo è assolutamente impraticabile.

Servirebbe una struttura di oggetti in grado di capire la semantica di ciascun tag e che mi consenta quindi di manipolare i dati, in Java, in base al loro reale significato anzichè alla loro posizione nell'albero del DOM.

Ed è qui che entra in gioco Castor.


Step 1: si prende lo schema XSD, che descrive come deve essere fatto l'XML che vogliamo ravanare in Java, e lo si dà in pasto al task ant di Castor.

Il task ant genera automagicamente una classe Java per ogni tipo di tag XML definito nell'XSD, con tutte le proprietà e le associazioni del caso.

Esempio, poniamo di avere un XML siffatto:

<root>
<person happy="true">
<name>Raibaz</name>
<surname>Raibaz</surname>
</person>
</root>

L'ant di Castor genererà una classe Root, con un array di Person, ciascuna delle quali avrà un name, un surname e una proprietà happy.

Voila oggettificato l'XML.

Step 2: per ravanare i dati XML, la classe dell'elemento radice ha due metodi statici, marshal e unmarshal, che rispettivamente fanno da Java a XML e viceversa.

Fine.

I dati XML sono completamente mappati su oggetti Java e posso completamente dimenticarmi della loro struttura originaria e di come fare il passaggio da e verso di essa.

Tra l'altro, la generazione di codice di Castor fa anche un sacco di cose molto fiche tipo che se hai un elemento XML che può assumere solo determinati valori (chessò, nell'XSD l'hai definito usando xs:restriction), ti crea da solo l'Enumeration, a scelta se 1.4 o java 5 compliant, con tutti i possibili valori.

Pregio assoluto, non ho altre parole.

Tra l'altro mi pare che Castor faccia la stessa cosa anche coi database oltre che con l'XML, ma non ci ho giocato perchè tanto per l'ORM c'è Hibernate che basta e avanza :)

3 commenti:

Luca ha detto...

(mi era partito il commento)
Anche JAXB ti crea il binding java partendo dallo Schema, e ha il vantaggio di essere endorsed dalla Sun ;)
In più ha un serie di direttive XML astruse al punto giusto per customizzare il binding.

K.

Matteo ha detto...

Per questo tipo di cose butta sempre un occhio sul sito dell'Apache Foundation, ci sono sempre tanti *bei* progetti interessanti in merito.

E se mai ti dovesse capitare di usare Groovy, ti consiglierei di usare X-stream (che btw forse funziona bene anche per Java...)

Ne approfitto per chiedere: ma oggi è il world-Stringhe-day ? Hai visto il messaggio sulla ML di ls-inginf-como ?!

- Tari aka Manga

Raibaz ha detto...

Si mi riferivo proprio a JAXB quando parlavo di framework equivalenti a Castor che dal jdk 6 sono endorsed :)

@Tari: sul sito dell'Apache foundation non ho trovato niente di più ad alto livello di xerces che costruisce solo il DOM...ma magari mi son perso qualche pezzo io.

Btw il messaggio sulla vecchia ML è veramente intrigante...adesso vedo se mi viene qualche idea...

Cmq ciao ammisci, era un sacco che non vi sentivo :)

Come state?