MokaByte 58 - Dicembre 2001 
foto dell'autore non disponibile
Xbean
Xbean la prossima generazione di JavaBeans: come semplificare il processamento di documenti XML
di
Giancarlo
Crecetti
La trasformazione di documenti XML e' alla base di molti sistemi di scambio di dati o di ERP System. Gli Xbean promettono di facilitare tale processamento

Introduzione
Nel mercato odierno XML sta di fatto diventando lo standard per lo scambio di informazioni tra applicazioni. Non soltando aziende, ma anche organizzazioni per lo sviluppo di business protocols come RosettaNet, utilizzano XML come lo standard di riferimento per transazioni.
Molta strada e' stata fatta, specialmente in Java, nel costruire APi per facilitare la manipolazione e la trasformazione di documenti XML. Esempi degni di essere menzionati sono naturalmente DOM (W3C Document Object Model), utilizzata in Xerces e Xalan, librerie di grande successo, e JDOM, piu' semplice, ma meno flessibile.
Un interessante nuovo sviluppo nel mondo XML e' l'introduzione degli Xbean: piccoli e semplici componenti che accettano un documento XML come input, lo processano e, in qualche modo, lo passano ad un altro Xbean per una ulteriore trasformazione.

 

Xbean
E' possibile pensare agli Xbean come una catena di componenti ognuno dei quali applica una trasformazione ad un documento XML sorgente. L'insieme degli Xbean viene chiamato Canale. Concetto simile alle pipes in Unix.


Figura 1 - Canale


Con questo tipo di approccio possiamo costruire delle semplici librerie che possono essere riutilizzate per trasformare documenti XML in una varieta' di modi diversi. E' bene sottolineare che gli Xbean ricevono e trasmettono documenti DOM e non stringhe che devono essere parsate da un XML parser.
Un Xbean e' un JavaBean che trasforma documenti XML. Questo significa che un Xbean ha la classica struttura di un JavaBean:

  • Costruttore con zero argomenti
  • Metodi Set e Get per modificare proprieta'

in piu', gli Xbean, utilizzano bean event per comunicare tra di loro. Questo e' un concetto chiave perche', come abbiamo accennato nell'introduzione, gli Xbean formano una catena di trasformazione in cui ogni elemento applica una trasformazione ad un documento XML. Naturalmente dopo la trasformazione l'Xbean deve passare il documento cosi trasformato all'anello successivo della catena: questo passaggio viene effettuato utilizzando un bean event.
L'Xbean, come ogni altro Java Bean, utilizza la delega di eventi come modello di comunicazione. In tale modello la comunicazione avviene attraverso il passaggio di event objects.
In particolare sono tre gli elementi che definiscono il modello di comunicazione tra Xbean:

  1. Event Object
  2. Event Source
  3. Event Listener

L'implementazione avviene attraverso:

  • un normale documento DOM come Event Object;
  • l'interfaccia DOMSource come Event Source
  • l'interfaccia DOMListener come Event Listener.

Vediamo in maggior dettaglio queste interfacce.

 

DOMSource interface
Due metodi vengono definiti in questa interfaccia: setDOMListener(DOMListener destinatario) e getDOMListener() per definire e ritornare l'Xbean che riceverà l'evento.
Un Xbean che implementa la sola interfaccia DOMSource viene chiamato Xbean Sorgente.


Figura 2 - Xbean Sorgente

 

DOMListener interface
Definisce un'unico metodo documentReady(DOMEvent evt) che viene chiamato dall'Xbean sorgente per passare il documento XML. E' all'interno di questo metodo che viene eseguita la trasformazione sul documento XML ricevuto. Dopo la trasformazione il documento viene eventualmente passato al successivo anello della catena. Un Xbean che implementa la sola interfaccia DOMListener viene chiamato Sink Xbean.


Figura 3 - Sink Xbean

Quando si parla di trasformazioni su documenti XML, viene naturalmente alla mente XSL. Anche se l'idea originaria non parla esplicitamente dell'utilizzo di XSL per la fase di trasformazione, questa e', a mio parere, il modo piu' elegante ed efficace per trasformare documenti XML.
Nella letteratura Xbean c'e' un'accenno all'utilizzo di XSL. in particolare se si utilizza XSL nella fase di trasformazione, il bean risultante viene chiamato XSLTransformBean. in questo caso viene utilizzata la libreria Xalan per applicare l'XSL stylesheet e generare il documento risultante. L'XSLTransformBean necessita di due nuovi metodi:

  • setStylesheetName(String nome)
  • setXSLTResultTarget(Object obj)

il risultato puo' essere diretto su un file, uno stream di byte o di caratteri oppure un documento DOM che puo' essere passato ad un altro Xbean per un ulteriore trasformazione. il processDocument() metodo verra' esplicitamente riscritto per utilizzare la XSLTProcessorFactory allo scopo di istanziare una implementazione della interfaccia XSLTProcessor.
Per concludere questo sezione e passare quindi ad un esempio concreto vorrei sottolineare il fatto che gli Xbean sono "lightweight component", cioe' molto semplici e con poche linee di codice. Noterete questa particolarita' negli esempi che seguiranno.

 

Esempi di uso degli Xbean
Scambio di Dati tra enterprises - Gli standard adottati in ogni singola enterprise possono essere descritti attraverso XML Data Type Definitions (DTD) che rappresentano la semantica ed il formato dei dati che devono essere scambiati. Ma ogni enterprise rappresenta i propri dati in modo diverso e l'idea che vogliamo adottare e' quella di raccogliere i dati originali nel database sorgente, trasformarli nel corrispettivo XML secondo uno standard definito da qualche DTD, trasportarli, trasformarli ancora nel formato adottato nell'enterprise di destinazione e finalmente memorizzarli. Questo tipo di trasformazione e' alla base di molti ERP System presenti oggi sul mercato.


Figura 4 - Semplice Sistema ERP

Ogni Xbean e' configurato in maniera opportuna:

  • L'Xbean Connector viene configurato per eseguira una particolare SQL query e trasformare il risultanto in un documento XML che soddisfa il particolare DTD dell'azienda.
  • il Translator trasforma il document XML ricevuto dal Connector in un nuovo documento XML conforme al formato accettato come formato di scambio. Anche in questo caso un DTD viene utilizzato per verificare il documento.
  • Gli Xbean sender e receiver vengono utilizzati come trasporto di dati ed non effettuano nessuna trasformazione, o se volete, una trasformazione identita' in cui il documento in input e' uguale a quello in output.
  • il Traslator sul lato destinazione trasforma il documento nel formato conforme all'azienda di destinazione.

Generici Xbean
Gli Xbean Generici processano ogni tipo di documento XML utilizzando la DOM APi e configurati utilizzando il meccanismo standard del property file. Di seguito viene riportata una lista di generici Xbean utili in molte applicazioni:

Accessor: questo Xbean viene utilizzato per eseguire particolari SQL query e rappresentare il risultato come un documento XML. L'Accessor puo' anche essere utilizzato per ricevere un documento come input e memorizzarlo attraverso una SQL query.

Translator: traduce un documento XML da un arbitrario DTD ad un'altro.

Sender/Receiver: questo particolare Xbean sono utilizzati per trasmettere documenti XML attraverso qualsiasi tipo di network. Naturalmente diverse implementazioni offrono diversi meccanismi di trasporto. importante osservare che questi Xbean non applicano nessuna trasformazione al documento che ricevono, o meglio applicano la trasformazione identita' in cui l'input e' uguale all'output.

Viewer: Visualizza il contenuto di un documento XML utilizzando uno Swing Tree.

Parser: Converte un documento XML dal suo formato testuale alla sua rappresentazione DOM.

Writer: Converte un documento DOM nella sua rappresentazione testuale e lo memorizza in un file.

Logger: Crea una log entry ogni volta un documento XML viaggia attraverso il Logger.

Parallelizer: Questo Xbean riceve un singolo DOM che viene passato a molteplici listeners.

Synchronizer: Riceve molteplici DOM che vengono passati and un singolo listener.


Esempio Reale
Per avere una maggiore confidenza nell'uso degli Xbean, costruiamo un esempio reale. Nel nostro esempio costruiremo un sistema che legge dati da un database sorgente, li trasforma e che memorizza in un database destinazione. il formato dei dati dal database sorgente a quello destinazione e' ovviamente diverso e rappresentato mediante uso di XML files.
Vediamo il sistema che andremo a costruire:


Figura 5 - Sistema d'esempio

Potete pensare ai due database come archivi che appartengono a due applicazioni diverse, e questo esempio come un semplice caso di sistema ERP in cui applicazioni possono comunicare tra di loro. La trasformazione verra' applicata utilizzando una catena di Xbeans.
Come db sorgente ho utilizzato MS SQL ed utilizzato, come database sorgente, il famoso Northwind. La tabella prescelta e' "Orders" con la seguente struttura:

Come destinazione ho utilizzato lo stesso database (in realta' dovrebbe essere un database completamente diverso) e la tabella in cui le informazioni, trasformate, ha la seguente struttura:

Da osservare che il sistema destinazione avra' il proprio numero d'ordine ed il codice cliente sara' il codice assegnato all'azienda sorgente dall'azienda destinazione. il POReference sara' l'Orderid nella tabella sorgente. il mapping che verra' eseguito sara':


Figura 6 - Mapping dei dati


 

XFileReader
Questa classe estende direttamente Xbean ed aggiunge il metodo setFile(String f) per leggere il file XML specificato. il metodo documentReady() parsa semplicemente il file letto e costruisce un documento XML Dom. il documento costruito viene quindi passato al componente successivo.


Figura 7 - XFileReader

 

XQueryBean
Questo Xbean viene utilizzato per eseguire delle query su un db. in particolare le informazioni necessarie per la connesione al DB e la stessa query vengono specificate nel documento XML in input. Nel nostro caso il file letto dal XFileReader.



Figura 8 - XQueryBean


in questo esempio, per la connessione al database verra' utilizzato il bridge ODBC che e' parte integrante della Java JDK e quindi disponibile a tutti. Per eseguire questo esempio potete utilizzare un database qualsiasi, anche Access e create una system DSN in modo da accedere al database attraverso il bridge.

il formato del file XML e' il seguente:

… xml header …
<connection>
<dsn> specificare il driver da utilizzare </dsn>
<user> user id </user>
<password> password </password>
<sql_query> select statement </sql_query>
</connection>

Non ho speso molto tempo sul formato di questo file, ma e' possibile modificarlo per una connection pooling utilizzando JNDi.
Per lo sviluppo di questo esempio ho utilizzato una system ODBC chiamata "XbeanSource" ed il file di connessione utilizzato e' il seguente:

<?xml version="1.0" ?>
<connection>
<dsn>XbeanSource</dsn>
<userid></userid>
<password></password>
<sql_query>select * from orders</sql_query>
</connection>


il metodo documentReady esegue la query sul database specificato dai parametri passati ed il resultSet ricevuto come risultato viene trasformato in un documento XML nel modo seguente:

<resultset>
<record id="1">
<columnName1>Value1</columnName1>
….
<columnNamen>Valuen</columnNamen>
</record>
….
<record id="k">
<columnName1>Value1</columnName1>
….
<columnNamen>Valuen</columnNamen>
</record>
</resultset>


Xtransform
Anche questo componente e' molto semplice: riceve un documento DOM che viene trasformato utilizzando un file XSL. il risultato viene quindi passato al successivo anello della catena, nel nostro caso un XDBWriter.
il metodo setXslFile(String f) viene utilizzato per specificare il file xsl utilizzato per la trasformazione. il metodo processDocument chiama semplicemente il processore XSLT per la trasformazione. in questo esempio e' stato utilizzato il processore Xalan 1.0.


Figura 9 - Xtransform


il documento trasformato conterra' le informazioni necessarie per memorizzare i dati nel database destinazione. in particolare verra' utilizzato il seguente formato:

… xml header …
<target>
<connection>
<dsn> specificare il driver da utilizzare </dsn>
<user> user id </user>
<password> password </password>
</connection>
<recordset>
<record table="nome tabella">
<column_name>value</column_name>

<column_name>value</column_name>
</record>

<record table="nome tabella">
<column_name>value</column_name>

<column_name>value</column_name>
</record>
</recordset>
</target>

Nell'esempio e' stato utilizzato il seguente xsl stylesheet:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<target>
<connection>
<dsn>XbeanTarget</dsn>
<userid></userid>
<password></password>
</connection>
<recordset>
<xsl:for-each select="/table/record">
<record table="TargetOrders">
<POReference type="char"><xsl:value-of select="OrderiD"/></POReference>
<Clientid type="char">AZS010</Clientid>
<OrderReceived type="char"><xsl:value-of select="OrderDate"/></OrderReceived>
</record>
</xsl:for-each>
</recordset>
</target>
</xsl:template>
</xsl:stylesheet>

Come potete notare ho preferito inserire le informazioni per la connessione direttamente nel file trasformato, ma riconosco che questa scelta, seppur valida, non e' molto elegante. Prendetevi la liberta' di utilizzare l'approccio a voi piu' consono. E' possible ad esempio inserire un nuovo metodo nella classe XDBWriter per poter specificare un file di connessione, oppure leggere un file specifico nel costruttore della classe XDBWriter quando questa viene instanziata.
La tag "column_name" viene utilizzata come nome del field in cui inserire il valore "value" nella tabella destinazione, indicata a sua volta, dall'attributo "table" dell'elemento "record".

 

XDBWriter
Questo componente si occupa di memorizzare le informazioni contenute nel documento DOM ricevuto sul database destinazione. Tutte le informazioni necessarie per la connessione e per il mapping nel database destinazione sono fornite dal file xml in input. il metodo processDocument esegue quindi i seguenti passi:

  1. Utilizzando il file in input, crea una connessione con il db destinazione;
  2. per ogni tag 'record'' esegui una iNSERT sulla tabella specificata dall'attributo 'table' i valori da inserire nella colonna column_name sono specificati da 'value'


Figura 10 - XDBWriter

Di seguito riporto i listati dei componenti sopra descritti. La classe Controller e' la classe che definisce la catena di Xbean e che inizia il processo di trasformazione.


Controller.java

import java.beans.Beans;
import java.io.*;
import com.ERPexample.*;

// Questa classe definisce il canale di Xbeans e inizializza la catena di eventi
public class Controller extends Object
{
public Controller()
{
}

public static void main(String args[])
{
//Descriviamo ora la catena che forma il canale di Xbeans
String reader="com.ERPexample.XFileReader";
String query="com.ERPexample.XQueryBean";
String transform="com.ERPexample.XTransform";
String writer="com.ERPexample.XDBWriter";

try
{
// instanzia ogni elemento del canale
com.ERPexample.XFileReader xfr=(com.ERPexample.XFileReader)Beans.instantiate(null,reader);
com.ERPexample.XQueryBean xqb=(com.ERPexample.XQueryBean)Beans.instantiate(null,query);
com.ERPexample.XTransform xtr=(com.ERPexample.XTransform)Beans.instantiate(null,transform);
com.ERPexample.XDBWriter wtr=(com.ERPexample.XDBWriter)Beans.instantiate(null,writer);

// Crea la catena di Xbeans
xfr.setFile("d:\\test\\connection.xml");
xtr.setXslFile("d:\\test\\DatabaseMapping.xsl");

xfr.setDOMListener(xqb);
xqb.setDOMListener(xtr);
xtr.setDOMListener(wtr); // Fine della catena

// inizializza il processo
xfr.processDocument();
}
catch (Exception e)
{
System.out.println("Error: "+e.getMessage());
}

}
}

XFileReader.java

package com.ERPexample;

import com.ERPexample.*;

import org.xbeans.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.inputSource;
import org.apache.xerces.parsers.DOMParser;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class XFileReader extends Xbean
{
private String fileName;
private Document doc;
private inputSource is;
private DOMParser parser=new DOMParser();

public void setFile(String f)
{
is=new inputSource(f);
fileName=f;

System.out.println("XFileReader->setFile called "+ fileName);
}

public void processDocument()
{
if (fileName!=null)
{
try
{
parser.parse(is);
doc=parser.getDocument();

DOMEvent devent=new DOMEvent(this,doc);
doml.documentReady(devent);
}
catch (Exception e)
{
System.out.println("Error: "+e.getMessage());
}
}
System.out.println("XFileReader->processDocument called");
}

public XFileReader()
{
}
}



XqueryBean.java

package com.ERPexample;

import com.ERPexample.*;
import org.xbeans.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.apache.xerces.parsers.DOMParser;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.net.*;
import java.sql.*;
import java.io.*;

public class XQueryBean extends Xbean
{
String dsn;
String query;
String userID;
String password;
Connection conn;
DOMParser parser=new DOMParser();

public XQueryBean()
{
}

public Document getDOMFromRecordset()
{
StringBuffer XMLString=new StringBuffer();
Document result=null;
int count=0;
String value;
String[] column;

if (dsn!=null)
{
try
{

// Utilizzando le informazioni lette dal file XML
// crea una connessione verso il db ed esegui la query specificata.
Class.forName ( "sun.jdbc.odbc.JdbcOdbcDriver" );
if (userID!=null)
conn = DriverManager.getConnection ("jdbc:odbc:"+dsn,userID,password);
else
conn = DriverManager.getConnection ("jdbc:odbc:"+dsn);

Statement stm=conn.createStatement();
ResultSet rs = stm.executeQuery(query);
ResultSetMetaData rsmd=rs.getMetaData();
int numColumns=rsmd.getColumnCount();

column=new String[numColumns];

for (int i=1;i<=numColumns;++i)
column[i-1]=rsmd.getColumnName(i);

// Costruisci la stringa XML risultante seguendo il formato
// descritto nell'articolo
// In questo caso dobbiamo specificare la codifica utilizzata
// perche' nella tabella "orders" vengono utilizzati caratteri
// unicode che non fanno parte della codifica standard

XMLString.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n");
XMLString.append("<table>\n");
while (rs.next()) {
XMLString.append(" <record id=\""+count+"\">\n");
for (int i=1; i<=numColumns; i++){
value=rs.getString(i);

//Replace the & with a space
if (value!=null && value.indexOf("&")>-1)
value=value.replace('&',' ');
XMLString.append(" <"+column[i-1]+">"+value+"</"+column[i-1]+">\n");
}
XMLString.append(" </record>\n");
count++;
}
XMLString.append("</table>");

conn.close();

//System.out.println("XMLString:"+XMLString);

//Costruisci il documento DOM risultante
ByteArrayInputStream bais=new ByteArrayInputStream(XMLString.toString().getBytes());
InputSource is=new InputSource(bais);
parser.parse(is);
result=parser.getDocument();

System.out.println("XQueryBean ha generato il documento di output correttamente ...");
//System.out.println("XQueryBean result: "+XMLString.toString());
}
catch (Exception e)
{
System.out.println("An error occured: " + e.getMessage());
conn=null;
}
}
return result;
}

public void getDBInfo(Document d)
{
NodeList figli=d.getChildNodes().item(0).getChildNodes();
Node temp;

// Mi aspetto il formato descritto nell'articolo con soli
// Percorro il documento DOM ed estraggo le informazioni

for (int i=0;i<figli.getLength();i++)
{
temp=figli.item(i);
try
{
if (temp.getNodeName().equals("dsn"))
dsn=temp.getChildNodes().item(0).getNodeValue();
if (temp.getNodeName().equals("userid"))
userID=temp.getChildNodes().item(0).getNodeValue();
if (temp.getNodeName().equals("password"))
password=temp.getChildNodes().item(0).getNodeValue();
if (temp.getNodeName().equals("sql_query"))
query=temp.getChildNodes().item(0).getNodeValue();
}
catch (Exception e)
{
//Probabilmente un valore null
//Ignora e continua
}
}
System.out.println("dsn:"+dsn+" userID:"+userID+" query:"+query);
}

public Document processDocument(Document d)
{
Document result=null;

System.out.println("XQueryBean->processDocument called");
try
{
if (d!=null)
{
getDBInfo(d);
result=getDOMFromRecordset();
DOMEvent devent=new DOMEvent(this,result);
}
}
catch (Exception e)
{
System.out.println("Error: "+ e.getMessage());
}

return result;
}

}


XTransform.java

package com.ERPexample;

import com.ERPexample.*;
import java.io.*;
import org.xbeans.*;
import org.w3c.dom.*;
import org.apache.xerces.dom.Documentimpl;
import org.xml.sax.SAXException;
import org.apache.xalan.xslt.*;
import org.xml.sax.inputSource;

public class XTransform extends Xbean
{
private String xslFile;
private XSLTinputSource xsltis;

public void setXslFile(String f)
{
xslFile=f;
xsltis=new XSLTinputSource(xslFile);

System.out.println("XTransform: setXslFile() method called ...");
}

public Document processDocument(Document d)
{
XSLTResultTarget result=null;
Document xresult=new Documentimpl();

if (d!=null){
try
{
// Assegna un processore XSLT
XSLTProcessor proc=XSLTProcessorFactory.getProcessor();

// Considera il documento ricevuto dall'Xbean precedente
XSLTinputSource input = new XSLTinputSource(d);

// Prepara il risultato e processa il documento
result=new XSLTResultTarget(xresult);

// Utilizza questa linea per trasferire l'output su un file
// e vedere il risultato della trasformazione.
//result=new XSLTResultTarget("d:\\test\\result.xml");
proc.process(input,xsltis,result);
}
catch (Exception e)
{
System.out.println("Error: "+e.getMessage());
}
}
System.out.println("XTransform: processDocument() executed ... result: \n");
return xresult;
}

public XTransform()
{
}
}


XDBWriter.java

package com.ERPexample;

import com.ERPexample.*;
import org.xbeans.*;
import org.w3c.dom.*;
import org.xml.sax.inputSource;
import org.apache.xerces.parsers.DOMParser;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.net.*;
import java.sql.*;
import java.io.*;

public class XDBWriter extends Xbean
{
String dsn;
String useriD;
String password;
Connection conn;
DOMParser parser=new DOMParser();

public void getDBinfo(Document d)
{
NodeList figli=
   d.getChildNodes().item(0).getChildNodes().item(0).getChildNodes();
Node temp;

// Mi aspetto il formato descritto nell'articolo.
// Percorro il documento DOM ed estraggo le informazioni.

for (int i=0;i<figli.getLength();i++)
{
temp=figli.item(i);
String name=temp.getNodeName();
try
{
if (name.equals("dsn"))
dsn=temp.getChildNodes().item(0).getNodeValue();
if (name.equals("userid"))
useriD=temp.getChildNodes().item(0).getNodeValue();
if (name.equals("password"))
password=temp.getChildNodes().item(0).getNodeValue();
}
catch (Exception e)
{
//Probabilmente un valore null
//ignora e continua
}
}
System.out.println("dsn:"+dsn+" useriD:"+useriD);

try
{
Class.forName ( "sun.jdbc.odbc.JdbcOdbcDriver" );
if (useriD!=null)
conn =
   DriverManager.getConnection ("jdbc:odbc:"+dsn,useriD,password);
else
conn = DriverManager.getConnection ("jdbc:odbc:"+dsn);
}
catch (Exception e)
{
System.out.println("Errore nella creazione della connessione: "+e.getMessage());
}
}

public void writeRecord(Document d)
{
// Considero il nodo "recordset"
NodeList figli=
d.getChildNodes().item(0).getChildNodes().item(1).getChildNodes();
NodeList recordNode;
StringBuffer fields=new StringBuffer();
StringBuffer values=new StringBuffer();

// Per ogni nodo "record" considera la tabella in cui inserire il
// nuovo record e inserisci i campi specificati
for (int i=0;i<figli.getLength();i++)
{
fields=new StringBuffer();
values=new StringBuffer();
recordNode=figli.item(i).getChildNodes();
String table=figli.item(i).getAttributes().item(0).getNodeValue();
for (int j=0;j<recordNode.getLength();j++)
{
// Estrai il nome del campo ed il suo valore
String field=recordNode.item(j).getNodeName();
String type=
  recordNode.item(j).getAttributes().item(0).getNodeValue();
String value=
  recordNode.item(j).getChildNodes().item(0).getNodeValue();

fields.append(field);
if (type.equalsignoreCase("char"))
values.append("'"+value+"'");
else
values.append(value);
if (j<recordNode.getLength()-1)
{
fields.append(",");
values.append(",");
}
}
// inserisci il record nel database destinazione
try {
String sql="iNSERT iNTO " + table + " ("+fields+") VALUES (" +
values + ")";
System.out.println(sql);
Statement stm=conn.createStatement();
if (stm.execute(sql))
System.out.println("XDBWriter-> La iNSERT non e' andata a buon fine ...");
else
System.out.println("XDBWriter-> Un nuovo record e' stato aggiunto alla tabella " + table);
}
catch (Exception e)
{
System.out.println("XDBWriter: "+e.getMessage());
}
}
}

public Document processDocument(Document d)
{

Document result=null;

System.out.println("XDBWriter->processDocument called");
try
{
if (d!=null)
{
// Estrai le informazioni per la connessione
// Anche in questo caso mi aspetto un xml file
// del formato descritto nell'articolo
getDBinfo(d);

writeRecord(d);
//result=getDOMFromRecordset();
DOMEvent devent=new DOMEvent(this,result);
}
}
catch (Exception e)
{
System.out.println("Error: "+ e.getMessage());
}

return result;

}

public XDBWriter()
{
}
}

Ricordate di includere la Xbean library quando proverete questi esempi. La libreria e' disponibile presso www.xbeans.org. includete anche le librerie Xalan 1.0 e Xerces 1.0. Potete trovare i sorgenti con le rispettive librerie presso l'ftp server di www.noususa.com dentro il folder /pub/Xbean. Utilizzate "Xbean" come userid e password.

 

Conclusione
Gli Xbean sono un interessante e valido strumento per la manipolazione e trasformazione di dati provenienti da diverse sorgenti. Particolarmente adatti nell'uso di applicazioni JSP per la loro naturale semplicita' e velocita' di esecuzione. inoltre la loro specializzazione permette una facile riconfigurazione del sistema per arrivare a soluzioni diverse riutilizzando gli stessi componenti. Nella vita reale la combinazione di Xbeans insieme con XSL si e' rivelata vincente in molti progetti di ERP integration.

Per qualsiasi dubbio o curiosita' potete contattarmi a gcrocetti@mokabyte.it

Bibliografia:
[1] Bruce Martin - "Xbeans" White Paper, www.xbeans.org
[2] O'Donahue John - "The new face of Java Beans" - 2000
[3] Sun - Java Beans APi, java.sun.com


Giancarlo Crocetti si e' laureato in Scienze dell'informazione all'universita' "La Sapienza" di Roma per poi conquistare il Master in Computer Science alla Rutgers University del New Jersey nel 1998. Dal 1996 vive a New York dove lavora come consulente per importanti aziende ed enti governativi come: Computer Science Corporation, United Nations, Merrill Lynch, Lockheed Martin e per il governo degli Stati Uniti.
Da piu' di quattro anni il 60% dei sistemi da lui architettati e sviluppati vengono implementati utilizzando tecnologie Java. Nel 2000 ha creato la propria azienda Nous USA inc., che offre servizi di consulenza e di training concentrate soprattutto su tecnologie Java.


MokaByte® è un marchio registrato da MokaByte s.r.l. 
Java®, Jini® e tutti i nomi derivati sono marchi registrati da Sun Microsystems; tutti i diritti riservati 
E' vietata la riproduzione anche parziale 
Per comunicazioni inviare una mail a info@mokabyte.it