Avoid XML Schema restrictions

I am back on XML Schema design and I do really like it !

One of the challenge that I am facing now is including or not the UBL metalanguage in my schemas (see some video on the oasis website), an Oasis standard, as you can deduce.

As you can see from this file:

http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/common/UBL-UnqualifiedDataTypes-2.1.xsd

UBL metalanguage has elements which are based on the UN/CEFACT elements, see:

http://docs.oasis-open.org/ubl/os-UBL-2.1/xsd/common/CCTS_CCT_SchemaModule-2.1.xsd

So as you can see UN/CEFACT has ComplexType which are extended by adding optional attributes, while the UBL elements are sometime restrictions  on the attributes (by making them required) and sometimes the elements are just extended giving a freedom in a later moment to choose what to add.

Independently from  the current problem, it happens that we might not need all the attributes or simply all the elements for our schema.

So either we add restrictions or we copy the elements that we need in our schema but simplified.

Adding restrictions can be possible in two ways:

1) Restrict on the patterns, like the max length of an element, they are so called facets, see: http://www.w3.org/TR/xmlschema-0/#SimpleTypeFacets

2) Restrict on the number of elements or attributes, in the case of the attributes  we need to make them prohibited

Conceptually both are restrictions based on an another type and this creates a problem in Object Oriented languages, like Java (hence the tittle of this post) which supports extensions (at the end a restriction is a sort of extension of a base object with some changes).

Jaxb is the official standard used for databinding XML elements to Java objects which relies on XJC for the conversion. Such standard adds Java annotations to associate XML elements to Java objects. Further, Jaxb relies on the validator of the marshaller by using the setSchema() method, see for example the post of Blaise Doughan, so in any moment you can validated your object against the schema to be sure before sending out your xml message.

For the facets, Jaxb doesn’t create annotations, there is still an open issue where 2 subgroups are working to solve it but still none of them are officially approved:

Other data bindings work on simple restrictions like enumerations (see Jibx) or numeric type and enumerations (see Xmlbeans, now archived).

You need also to consider that facets can change in the future (the max length could be extended from 100 characters to 200), so which impact has changing the xml schema? Since Jaxb doesn’t generate annotations for facets you don’t need to change the java objects but other databindings might be.

For the restriction on the the number of elements/attributes this CANNOT be reflected in a Object Oriented language because it is not possible to restrict an extended class on inherited properties. Therefore I suggest to copy simplified elements (by keep only those mandatory and removing the optionals), in this way:

  1. you have less dependency
  2. the developer has less method generated (just those needed)
  3. you keep compatibility at the minimum if you want to convert the copied object into the original objects

Therefore I would recommend to avoid restrictions if possible, you can keep them for the sake of validation but you need to think about the impact on the objects generated with the databinding libraries. Such recommandation is also expressed by the HP XML schema best practices (search for “restrictions for complex types”) and in Microsoft xml schema design pattern.

 

 

 

Advertisements

Netbeans, IReports e Xmlbeans

Ciao a tutti, in questo periodo mi sono avvicinato al mondo dei reports con JasperReports. Come realizzare un report tramite JasperReports ?

In pratica quando realizzate un report dovete definire un template che per JasperReports è un file xml in cui schema si trova a questo link: http://jasperreports.sourceforge.net/xsd/jasperreport.xsd

Il template è comunemente detto file jrxml che deve essere compilato in formato jasper. La realizzazione del template è aiutata da un plugin per Netbeans che permette di fare un drag and drop degli elementi anche se alla fine andrete di sicuro a modificare il file template a mano

Fatto sta che nel file potete mettere direttamente delle query che restituiscono tabelle con i rispettivi nomi di colonne a cui associare delle variabili che potete usare per creare le intestazioni per le tabelle o grafici che andrete ad inserire nel vostro template.

Le query possono anche essere esterne e questo ritengo sia un bene ma la particolarità è che una volta fissato un template e compilato nel formato jasper sarà quello una volta per sempre. Supponendo che si vuole creare un report per ogni tabella di un database si pensa subito al fatto che il numero delle colonne puo’ variare.

Percio’ stavo pensando perchè non prendere lo schema e generare il jar con Xmlbeans per poter creare il template al volo in java?

Nel fare cio’ ho avuto un intoppo, l’elemento Text è definito come complexType nel seguente modo:

<element name=”text”>
<complexType mixed=”true”>
</complexType>
</element>

Cioè in pratica è vuoto e l’unico metodo che mi rimane per riempirli è usare l’istruzione set su un XmlObject o l’XmlCursor che prevede un XmlObject da inserire.

Nella realizzazione di un template jrxml questo campo viene riempito con valori CDATA. Ho notato che esistono dei metodi nella classe XmlOptions che servono per inserire CDATA e li ho provati ad usare ma senza successo, magari ho sbagliato qualcosa.

Ci riproverò.

Nota:

http://markmail.org/message/ykiztut4p2tcalfh#query:node.setKey+page:1+mid:dhr2i74v7rkjf4ti+state:results

Web Services: stili, overloading e databinding

Nei precedenti post avevo già segnalato il fatto che per mantenere l’interoperabilità dei web services, partendo da un file wsdl, occorre rispettare il cosiddetto Basic Profile 1.1. Il Basic Profile non fa altro che far applicare delle restrizioni sulla scrittura del file wsdl in modo tale da garantire una certa interoperabilità.

L’interoperabilità non significa che tutto puo’ funzionare come vogliamo noi e difatti uno dei problemi di cui vi sto accennando nell’articolo è il problema dell’overloading dei metodi.

Occorre dire che ci sono principalmente 2 modi per descrivere un file wsdl compatibile con il Basic Profile e questi sono RPC/literal e Document/literal (per maggiori dettagli vedere il seguente articolo). Fatto sta che tra le 2 quella più usata è Document/literal in versione “wrapped”.

Questa versione è usata in pratica da .NET di default mentre la versione RPC no, tra l’altro Microsoft fa parte del consorzio WS-I, di consequenza scegliere per scegliere uno stile conviene adottare questo in modo da essere interoperabili con .NET (non me ne vogliano i puristi ma io lavoro con web services in java e questi devono comunicare in web services in .NET).

Secondo l’articolo che vi ho linkato un esempio di file wsdl in stile Document/literal wrapped è il seguente:

<types>
    <schema>
        <element name="myMethod">
            <complexType>
                <sequence>
                    <element name="x" type="xsd:int"/>
                    <element name="y" type="xsd:float"/>
                </sequence>
            </complexType>
        </element>
        <element name="myMethodResponse">
            <complexType/>
        </element>
    </schema>
</types>
<message name="myMethodRequest">
    <part name="parameters" element="myMethod"/>
</message>
<message name="empty">
    <part name="parameters" element="myMethodResponse"/>
</message>

<portType name="PT">
    <operation name="myMethod">
        <input message="myMethodRequest"/>
        <output message="empty"/>
    </operation>
</portType>

Come vedete la sezione message contiene solo una “part” per input/output. La parte che contiene l’input ha l’elemento myMethod, nome che deve essere uguale al nome dell’operazione. L’elemento myMethod è quindi un tipo complesso definito da una sequenza di elementi.

Uno dei problemi messi in evidenza è l’impossibilità di fare overloading dei metodi perchè se il metodo myMethod  con i 2 parametri corrisponde all’elemento myMethod non è possibile aggiungere in xml un secondo elemento dal nome myMethod con un solo parametro per via dell’XML stesso.

Tuttavia il problema diciamo non si pone poichè solo con file WSDL 1.1 è possibile l’overloading mentre con file WSDL 2.0 no anche se l’adozione di quest’ultimo non trova piena applicazione.

A riguardo l’uso dello stile wrapped vi suggerisco un articolo tratto dal blog di  Anne Thomas Annes, esperta in web services, che ha collaborato con WS-I ed una interessante spiegazione in questa mailling list (vedere ore 13:43)

Il tutto ovviamente si ricollega al databinding perchè, stile a parte,  occorre scegliere il databinding, e il fatto che ADB e Jibx supportano lo stile unwrapped e wrapped mentre Xmlbeans solo wrapped  (vedi articolo) viene meno se scegliamo lo stile wrapped.

Personalmente uso Xmlbeans per una serie di metodi utili forniti dall’interfaccia che ogni oggetto xml implementa. Per alcuni dettagli sulla storia e struttura di xmlbeans suggerisco questo articolo (oltre che il sito ufficiale) di David Bau uno dei creatori di Xmlbeans.

Nota a parte: ADB e Xmlbeans sono databinding della Apache foundation. Xmlbeans in particolare è stato donato da Bea System (nel settembre 2003), una delle società fondatrici della WS-I, da sempre coinvolta nel campo dei web services con il suo Esb, e di recente (aprile 2008) comprata da Oracle altra società fondatrice e leadership della WS-I.

Non penso di rompervi più con il Basic Profile :-)

WSO2 Esb, WSAS e Xmlbeans

Piccola nota per quanti seguano le mie avvenure con questi software.

In pratica, poichè mi piace usare Xmlbeans come databinding invece di usare Adb, ho scoperto che quelli di WSO2 non hanno aggiornate alcune librerie.

Se in pratica avete usato Xmlbeans 2.3.0 (lo vedete tra le librerie dei vostri plugin di Axis2 per Eclipse) per la generazione dei vostri webservices e ne avete fatto il deploy su Esb o WSAS avrete la seguente eccezione:

org.apache.xmlbeans.SchemaTypeLoaderException: XML-Beans compiled schemas: Incompatible minor version – expecting up to 23, got 24

Questo in pratica accade perchè Xmlbeans si appoggia su Xbean e guarda caso nell’esb si trova Xbean 2.2.0 mentre in WSAS addirittura la versione 2.1.0 quando in entrambi c’è Xmlbeans 2.3.0.

Occorre quindi aggiornare Xbean che potete trovare a questo link:

http://www.eviware.com/repository/maven2/xmlbeans/xbean/2.3.0/

Ho fatto riferimento a WSO2 Esb 1.7.1 e WSO2 WSAS 2.3