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

JAXB and the root element

Recently I helped a friend to implement the client of a web service using Axis2 and Tomcat, developing the client first and the jsp after. After testing the web service with SoapUI we started to develop the client with Eclipse.

The problem with this web service is that the body of the method is an entire xml string contained in a CDATA element, not only for for the request but also for the answer, of course this creates problem to generate the java objects from the wsdl file since the element is not defined as XML.

Luckily we received the xsd files so we generated the java classes with JAXB data binding which is implemented, and it can be executed, through the application xjc that you can find inside the bin folder of the Java Virtual Machine. Note that JAXB is the default databinding of Apache Cxf.

JAXB worked nicely but we had the problem to extract from the xml string the node container which needed to be declared as root element, in other words you need to use the @XMLRootElement annotation otherwise you can have the exception:

unexpected element (…) , Expected elements are (none).

when you unmarshal (from string to java object) the element.

 

Galleon, un forum in Coldfusion

Si avete letto bene Coldfusion; benchè esso sia tecnologia proprietaria realizzata da Adobe, esistono diverse implementazioni libere e tra queste troviamo Railo.

Railo, come Adobe Coldfusion, è una applicazione Java che compila il codice coldfusion in classi java, la cui ultima versione 3.1 è rilasciata con licenza LGPL 2 come progetto di Jboss.

Railo può essere scaricato per i diversi sistemi operativi (Windows, Max, Linux), con Jetty o Resin o senza come un war file che deve essere copiato in un application server.

Io ho scaricato la versione 3.1.2 con Jetty per prova il che significa che dovete semplicemente eseguire il file start e recarvi all’indirizzo localhost:8888.

Una volta cambiata la password per motivi di sicurezza vi ritroverete nel pannello di amministrazione. Per installare Galleon dovete:

  1. creare un database MySQL che potete fare velocemente da Xampp
  2. andare nel pannello di amministrazione di Railo e sotto la voce Services -> Datasources creare un datasource di tipo mysql che si collega al database creato (utente e password sono quellli di MySQL)
  3. andare nel pannello di amministrazione di Railo e sotto la voce Extension – Applications spuntare la voce Galleon (forum hostato su RiaForge e creato da Raymond Camden) e cliccare sul pulsante install, il quale (dopo aver accettato la licenza Apache) vi redirige ad un form che dovete riempire (inserite il campo email che si trova nel mezzo del form anche se non richiesto altrimenti avrete una eccezione) e poi potete accedere al login di Galleon.

Una volta inseriti username/password (admin/admin) vi ritroverete di fronte al front-end, per il backend dovete andare su: http://localhost:8888/forum/admin/

Nel pannello di amministrazione di Galleon troverete un menu a sinistra dove potete:

  • creare Conferences, Forum, Thread, Messages
  • modificare i valori che avete inserito nella fase di installazione
  • gestire gruppi e utenti
  • consultare statistiche; se non avete configurato un server SMTP avrete un errore coldfusion per le statistiche generali, sono interessanti le stastitiche sulle parole cercate (magari si potrebbe connettere con Solr..)

Buona esplorazione !

Webclient for SVN, Hudson e Artifactory

Salve a tutti, in questi giorni mi sono addentrato ancora nel mondo del continuous integration perchè sto lavorando su un progetto in Java, gestito in outsourcing, dove aiuto un gruppo di sviluppatori ad utilizzare strumenti di sviluppo che facilitano il lavoro quali un sistema di continuos integration.

Sono partito da un progetto con subversion installato su una macchina e so che nel progetto usano Jboss con JDK 1.5 (ancora non so perchè)

Su un’altra macchina remota vado e installo JDK 1.5.0.22, Ant 1.7.1, Maven 2.2.1 (fino ad ora (2 mesi di progetto) hanno usato solo Ant e vorrebbero passare a Maven), Jboss 5.1.0, Webclient for SVN 3.1.0 e Artifactory 2.1.2.

Piccola nota: volevo usare Sventon ma l’ultima versione aveva problemi con le librerie e le precedenti mi davano anch’esse problemi.

Non sapete cosa è Artifactory ??? Allora è possibile che siete ancora freschi su Maven (non è che io non lo sia :-) )

Artifactory è una applicazione web che permette di gestire repository Maven, sviluppata in Java e rilasciata con licenza LGPL 3.0. L’applicazione è realizzata da JFrog Ltd, una società privata isreliana.

Strutturalmente si poggia su Apache Jackrabbit per l’implemetazione delle specifiche JSR 170 per il cosiddetto Java Content Repository (anche altri content manager come Nuxeo si appoggiano su Jackrabbit).

Piccola nota: la JSR 170 (rilasciata nel 2005) è seguita dalla JSR 283 da poco rilasciata (25 Settempre 2009) ed entrambe sono condotte da David Nuescheler, CTO della società svizzera Day Software.

Inoltre Artifactory si basa su Apache Lucene per indicizzare i file e Apache Wicket per l’interfaccia utente.

Ora l’applicazione è rilasciata come standalone ma esiste la versione war che può essere deployata su un application server e quindi l’ho messa su Jboss insieme ad Hudson e Webclient for SVN (questi 2 li ho poi legati con il plugin di hudson per Polarion che permette di linkare la lista di file modificati ai file presenti sul webclient e si possono anche vedere le differenze con le versioni precedenti).

La struttura è basata anche su database, di default Apache Derby ma che può essere cambiato (vedi anche qui).

A parte il fatto che Artifactory permette di base una autenticazione LDAP, quello che lascia senza parole è la semplicità di uso (andrebbe confrontato con Nexus ma non ne ho tempo, di sicuro nella versione base manca LDAP (anche se ho scoperto di recente che esiste un plugin di terze parti) e di sicuro gli sviluppatori hanno realizzato una bella guida a maven e un plugin per Eclipse). Una volta andato su

http://localhost:8080/artifactory

e loggato, sono andato sul pannello amministrativo e nella sezione repository ho creato un repository locale dove fare il deploy dei propri jar file e un repository virtuale in cui aggiungo quello locale più tutti i remoti quali quello di Maven, Jboss ecc ecc. Fatto ! Ora potete generare anche la sezione del file settings.xml da aggiungere nel vostro progetto Maven.

Per una vecchia guida vi rimando qui. Per un confronto con Nexus e Archiva vi rimando a questo link (attenzione è scritto dallo stesso autore della guida su Artifactory ma sembra serio)

Buon maven a tutti !

Nota: Webclient for SVN si basa su Subversion 1.4 (con versioni successive ho avuto problemi perchè usa un SVNKit vecchio che non posso aggiornare perchè c’è una particolare classe non più presente nelle ultime versioni), potete trovare Subversion 1.4 qui:

http://downloads-guests.open.collab.net/servlets/ProjectDocumentList?folderID=6

Netbeans 6.5.1 e Openfire 3.6.4

Oggi ho provato Openfire 3.6.4 un server XMPP scritto in Java rilasciato con licenza GPL.

Stavo pensando di fornire un servizio di chat e mi sono ricordato che quelli di Sun avevano messo il supporto a Netbeans chiamato Developer Collaboration ma come ho scritto in un precedente post c’erano problemi di compatibilità che ora sembrano superati con le nuove versioni di Netbeans.

Ho dapprima scaricato il file dal sito della Ignite Realtime (versione Mac OS X poi su Win), una volta installato me lo sono ritrovato in /usr/local/openfire. Dentro la cartella bin ho trovato il file openfire.sh ha cui ho dato i permessi di esecuzione ma che ho eseguito da root. Ho poi eseguito il file e sono andato nel mio browser (firefox) all’indirizzo:

http://localhost:9090

Tra le lingue a disposizione trovate Ceco, Tedesco, Inglese, Spagnolo, Francese, Olandese, Polacco, Portoghese Brasiliano, Sloveno e Cinese Semplificato.

Dopo le lingue impostate il vostro dominio con le porte 9090 e 9091. Dopo dovete scegliere se usare un database interno o esterno (potete scegliere tra MySQL, Oracle, Microsoft SQLServer, PostgreSQL, IBM DB2).

Ho scelto MySQL, ho impostato l’indirizzo di localhost e nel frattempo ho creato il database perchè Openfire non lo crea.

Ho poi scelto per il profilo di usare il database, alternativamente si può scegliere LDAP o ClearSpace. Infine ho poi impostato email e password di amministratore.

Alla fine della procedura avete necessità di riavviare il server perchè altrimenti la pagina di login non funzionerà !

Noto che il plugin search non è installato sulla versione di Openfire per Mac (su Win si, devo vedere su linux) e procedo ad installarlo.

Dopo di che come spiegato in questo post (ma anche nel primo link che vi ho dato) occorre creare una nuova Group chat; invece di usare “conference” ho creato “myconference”.

Poi sono andato su Netbeans, ho installato il plugin Developer Collaboration, e ho creato un nuovo account chiedendo di registrarmi sul server, alla fine della procedura di registrazione dovreste poter vedere il nuovo account sul server. Dovreste poi autenticarvi senza nessun problema.

Per fare una prova di chat ho usato Pidgin o Spark (rilasciato dalla stessa azienda) creando un utente sul server e loggandomi una volta con Pidgin e una volta con Spark. La chat diciamo che va, quando è l’utente su Pidgin che apre la conversazione con il client su Netbeans si vede un po’ di codice XML il contrario invece no. Occorre provare tra 2 istanze di Netbeans.

C’è da dire che Netbeans punta su Kenai per il servizio di chat vedi qui.

Nota: una mia collega usava QIP come chat client, per poterla riuscire a loggare sono dovuto andare in Jabber options->Advanced->Server option>Disable SASL authentication; notavo infatti che all’atto di scambiare il digest MD5 c’erano problemi.

Installazione veloce di Alfresco su Glassfish

Ho cominciato a valutare l’idea di installare un Document Management System per un progetto a cui sto lavorando e poichè  in un altro progetto ho notato che hanno installato Liferay che si appoggia su Alfresco ho pensato di cominciare con Alfresco appunto.

Avendo Glassfish 2.1 installato in locale, ho scaricato il file war di Alfresco dal seguente link:

http://process.alfresco.com/ccdl/?file=release/labs/build-1526/alfresco-labs-war-3Stable.tar.gz&a=y&s=n&t=y

che permette di scaricare la versione stabile di Alfresco Labs 3.1. Fate il deploy dell’applicazione da Glassfish ma non lo lanciate perchè altrimenti ricevete errore HTTP Status 503.

Come difatti spiegato nel wiki e in questo post che ho trovato, dovete creare manualmente il database su cui Alfresco si poggia altrimenti avete l’errore che vi ho detto.

Di default Alfresco si basa su MySQL e, sempre di default, il suo database è alfresco con username alfresco e password alfresco, tutto questo lo potete vedere nel file /alfresco/WEB-INF/classes/alfresco/repository.properties perciò usando PHPMyAdmin potete creare velocemente database e utente, fatto cio’ troverete alfresco all’indirizzo:

http://localhost:8080/alfresco

L’amministratore per default ha username admin e password admin (potete cambiarla una volta loggati oppure prima di creare il database andate nel file /alfresco/WEB-INF/classes/alfresco/web-client-config.xml ).

Buona esplorazione !

PS: ora sarei curioso come funziona l’integrazione con Drupal.

PS2: alternativamente stavo pensando a KnowledgeTree che si può integrare con Process Maker.

Web.xml e HTTPS: proteggere le vostre pagine JSP

Sono ai primi passi con JSP e sto creando una pagina di login per l’autenticazione, una di quelle banali con username e password che vanno verificate.

A parte impostare il form con method=”POST” mi sono chiesto come abilitare https per offrire una comunicasione sicura. Niente di più semplice, probabilmente nella vostra applicazione web vi ritrovate il web.xml già creato dal vostro IDE e che potete modificare.

Il file web.xml è chiamato deployment descriptor perchè esso descrive come la vostra applicazione composta da diversi file (o risorse) viene raggiunta dall’esterno, non solo in termini di URL ma anche in termini di sicurezza.

Come abbiamo capito il deployment descriptor è un file xml che è descritto da uno schema, l’ultima versione la 2.5 la trovate qui:

http://java.sun.com/xml/ns/javaee

cercate la voce Servlet Deployment Descriptor Schema.

Un semplice esempio lo trovate qui:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Potete notare la versione 2.5, lo schema web-app_2_5.xsd, il parametro di timeout (0 significa no time out) e il welcome file che contiene il file index.jsp che deve essere il primo ad essere visitato.

Per quanto riguarda la sicurezza, se vogliamo aggiungere la protezione su tutte le risorse e fare in modo che altre entità, terze persone, non vedano il contenuto trasmesso (in altre parole SSL), dovremo aggiungere appena prima del tag </web-app> la seguente configurazione:


<security-constraint>
<web-resource-collection>
<web-resource-name>secure</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>

è molto importante sapere che:

  • potete specificare più di un security constraint, vedere qui un esempio; nell’esempio potete notare che si può scegliere se applicare la sicurezza al solo metodo POST o GET o a tutti i metodi specificati nel protocollo HTTP 1.1
  • l’url-pattern /* indica tutte le pagine che si trovano subito dopo la / nell’URL, potete anche dire /main/* tutte le pagine che si trovano dopo /main/ nella loro url
  • il livello CONFIDENTIAL dice che altre entità non possono vedere il messaggio trasmesso, il sotto livello è INTEGRAL per cui il messaggio non può essere modificato in transito e NONE quando non si vuole alcuna garanzia sul trasporto

Ora non dovete far altro che il deploy della stessa applicazione e andare sul link http della vostra applicazione e verrete rediretti su HTTPS (accettando il certificato).

La versione 2.5 è destinata ad essere seguita dalla 3.0 come descritto dalla JSR 315 che introdurrà diversi miglioramenti tra cui l’uso delle annotazioni nelle servlet rendendo vano l’uso del file web.xml, ma tutto cio’ si accadrà su J2EE 6 e quando i diversi servlet-container saranno pronti per interpretarli.