martedì 20 gennaio 2009

Latex

Ho iniziato ad impaginare al tesi con latex... in realtà non ho ancora terminato di scriverla, mi manca uno dei due capitoli centrali...
ma almeno inizio a scrivere seriamente il tutto.

Prendo appunti su alcuni settaggi:

Voglio usare una doppia bibliografia, così da costrurire la classica bibliografia, e successivamente, una sitografia
Uso ovviamente bibtex, decisamente comodo
lo affianco al pacchetto multibib

quindi nella classe caricata all'inizio del documento, scrivo questi due comandi

\usepackage{multibib}
\newcites{sito}{Sitografia}

dove il newcites introduce proprio la seconda bibliografia e una serie di comandi (simili a quelli di bibtex, ma con l'aggiunta ad onuno del suffisso "sito") appositi

all'interno del documento principale, subito dopo al creazione della bibliografia, creo la sitografia in questo modo

\bibliography{bibliografia} % inserisce la bibliografia e la prende in questo caso d bibliografia.bib

%sitografia, prendendo i dati da sitografia.bib, dentro il quale uso "misc"%
\bibliographystylesito{alpha}
\bibliographysito{sitografia} 

All'interno del documento, usando il normale comando \cite citerò i documenti della bibliografia normale, usando il comando \citosito, utilizzo al sitografia


Per poter avere anche la sitografia, però, non posso usare il comodo comando preimpostato all'interno di TeXnicCenter "Build and View" (che compila tutto, crea il pdf, e lo visualizza), ma devo andare di riga di comando

latex tesi
bibtex tesi
bibtex sito
latex tesi
latex tesi

e qui si produce il file dvi

con il comando

dvips primo.dvi -o

si produce il file PostScript ps

lunedì 29 dicembre 2008

Effective Java

Da qualche settimana siamo fermi sullo sviluppo del framework (e quindi anche la mia tesi), ne ho approfittato, oltre che per migliorare il prototipo già funzionanente presso un nostro cliente, e per implementare nuove features richieste dal cliente stesso, per studiarmi uno dei libri che mi ero ripromesso di studiare: Effective Java.
Interessante direi, molto utile in qualche consiglio, meno in altri, ma direi un must.
Alcuni dei consigli trovati nel libro li ho già "implementati" nel framework, migliorando alcuni aspetti che erano già stati realizzati. E sicuramente molti altri ci saranno in seguito utili.
Lo consiglio a tutti, soprattutto a chi come me non è espertissimo nella programmazione di grandi progetti.

martedì 25 novembre 2008

TeePee

Dopo un po' di giorni senza post, forse è il caso di aggiornare un po' chi segue questo blog (e guardando dalle statistiche di google analytics non siete nemmeno pochi, lasciatemi gongolare, dai).

Nell'ultimo mese ci siamo dati completamente allo sviluppo del framework che fino dall'inizio volevamo sviluppare. Prima d'ora era poco più che un abbozzo, ma l'esperienza fatta nello sviluppare l'applicazione che già dei clienti stanno usando, ci ha permesso di trovare i reali bisogni di cui necessitiamo, e le carenze dei framework esistenti.

Il mio collega e correlatore ha gettato le basi, su cui ho costruito il resto, sempre sotto la sua supervisione.
Abbiamo anche deciso di rendere disponibile questo core del framework, rilasciandolos su google code con licenza GNU Lesser General Public License.
Il tutto lo trovate qui: http://code.google.com/p/teepee/
Ovviamente attualmente non si trova molto online, tranne il codice nudo e crudo, ma presto, anche ai fini della tesi, rilasceremo i javadoc e qualche file esplicativo, oltre a quelche schema UML.

A tale proposito, qualcuno ha quelche strumento (opensource o freeware) da consigliare? Per ora ho provato 
  • violetUML, non male, ma di fatto non utile nei sequence diagram
  • ArgoUml, buono per il reverse enginering, mi ha generato tutti i diagramma di classe per tutti le classi del progetto, niente male, fa risparmiare tempo... ma poi poco usabile per creare i diagrammi
  • Visual Paradigm... niente male, ma a pagamento
  • StarUml... quello che sto usando ora, opensource, non male, ma i grafici non sono personalizzabili al 100%... alcune cose rimangono standard, come i punti di ancoraggio delle linee, frecce e simili.

mercoledì 8 ottobre 2008

Ancora su Orm

Sono riuscito nel tentativo del salvataggio di una chiamata con hibernate/orm... ho in pratica trovato il modo per superare, più o meno, le restrizioni evidenziate in questo post(Alcuni problemi con gli id composti e i valori di default con Hibernate).

In pratica ho usato degli DAO molto più semplici... che non considerano in pratica le relazioni molti a molti... in pratica, all'interno della classe che rappresenta la tabella nel database, ogni riferimento a chiavi esterne... è memorizzato come un campo qualsiasi, ignorando assolutamente se nei DAO esiste una classe che potrebbe sostiurire il campo.

In pratica, prima, per esempio, se nella tabella chiamata evavo un campo id_imp che era ovviamente una chiava esterna per la tabella imp, il DAO era costituito come un field costituito da un elemento stesso della classe Imp... che a suo volta però al suo interno aveva un ID composito rappresentato dalla classe ImpId... ed è questo che pareva creare dei problemi.

Ora, con questi nuovi DAO più semplici, in un caso come quello sopra, id_imp è rappresentato nella classe Chiamata dal field chiamato idImp rappresentato da una semplice stringa... posso quindi assegnarli una semplice stringa... che rappresenta poi l'id chiave esterna di imp (imp ha il campo id come stringa)
In pratica come dovrei fare se usassi SQL.

Così sono riuscito a memorizzare senza problemi una chiamata assegnando tramite gli strumenti di HIBernate tutti i valori che mi interessano.
In realtà qualcosa di diverso c'è... tutti i campi sono memorizzati come dati primitivi, String, char, int, date... cioè come la definzione del campo nel database... tranne alcuni (pochissimi) come per esempio HdTipoContab, che è memorizzato ancora come classe... questo perchè (credo) proprio al tabella hd_tipo_contab non ha id composto (come invece il 99% delle altre tabelle) e quindi è comuinque molto semplice usarlo... anche se ho dovuto aggiungere un costruttore alla classe così come era stata creata automaticamente.

Questi DAO semplificati li ho ottenuti usando sempre Hibernate Tool, plugin di Eclipse, selezionando perà nel file di configurazione hibernate.revenge.xml solo el tabelle vere e proprie, ignorando le varie view presenti nel database, e selezionando, all'atto della creazione del codice, nessuna opzione particolare (quindi non selezionando"generate basyc typed composite id", nè "Decect optimistic lock columns", nè "detect many-to-many tables"), e nella schermata exporters, non ho selezionato nessuna delle opzioni in alto (quindi non ho selezionato nè "Use java 5 sintax" nè "Generate EJB3 annotations") e come exporters ho selezionato "domain code" (che genera le classi java che poi utilizzo), "Hibernate xml mapping .hbm.xml" (che genera i file xml per specificare ogni singola classe), "DAO Code" (che a quanto pare genera delle classi java chiamata come le precedenti+home... non so esattamente a cosa siano necessari, pare sempre ad hibernate), sia "Hibernate Xml Configuration, cfg.xml" che genera un nuovo hibernate.cfg.xml con i riferimenti ai file .hbm.xml che vengono generati.

domenica 21 settembre 2008

OpenLaszlo e Flex

OpenLaszlo e Flex sono stati due dei framwerok di sviluppo di RIA che avevamo inzialmente preso in considerazione. Li scartammo quasi immediatamente per il legame che questi framweork hanno (o meglio, nel caso di Laszlo, avevano) con Flash e per lo sviluppo in Javascript/Actionscript, e non Java.

Flex è un framework rilasciato da Adobe per la creazione di ria con un linguaggio markup proprio, MXML, basato su XML, utilizzato per descrivere il layout dell'interfaccia utente e i comportamenti, mentre ActionScript 3, linguaggio di programmazione orientato agli oggetti, utilizzato per creare la logica client. Il tutto compilato poi per la creazione di oggetti SWF per l'esecuzione tramite Flash Player.

OpenLazlo oper in maniera piuttosto simile, anch'esso con un linguaggio simil XML condito con un linguaggio di programmazione, Javascript, anch'esso poi compilato in file SWF.
Attualmente però la nuova versione di OpenLaszlo supporta anche la possibilità di sviluppare ria anche senza l'uso di flash, ma con dhtml/ajax (come gwt, in poche parole), ma questo supporto è stato introdotto solo con la versione 4.1, rilasciata a Luglio 2008... decisamente molto più tardi di quando la nostra scelta di frawork base su cui lavolare è caduta su GWT.

E' comunque interessante dare uno sguardo a questa tecnologia.
Grossomdo il paradigma di programmazione non è così distante da GWT... si programma in un linguaggio, il framework mette a disposizione un compilatore che processa i file sorgente e produce del codice che verrà poi eseguito sul client.
Il linguaggio di programmazione usato per OpenLaszlo è un markup language, LZX, linguaggio risultante dalla fusione di aspetti dichiarativi, derivanti dall' XML, con altri tipici della programmazione imperativa Object-Oriented, derivanti da JavaScript. Nei file sorgenti di OpenLaszlo infatti si utilizza una sintassi molto simile a quella di un classico file XML, con riferimenti alle API messe a disposizione del framwork, con l'aggiunta di codice JavaScript.
Il compilatore poi, processando questi file sorgenti, crea un file SWT (quindi un file per Macromedia Flash), che possa quindi essere eseguito da qualsiasi browser con il Flash Player. Recentemente è stato anche introdotto il supporto per la compilazione di codice slegato da Flash,
generando quindi codice DHTML/AJAX.
Comunque sia, il codice simil-Javascript scritto nei file LZX non è quello eseguito dal browser, ma viene intepretato dal compilatore e resituito come codice actionscript di Flash, nel caso si vada poi ad utilizzare la tecnologia di Macoromedia, o generando del nuovo codice Javascript nel caso di utilizzo del classico AJAX.

Pro:
  • La realizzazione dell'interfaccia utente risulta abbastanza semplice da realizzare, lineare e abbastanza riusabile. Il tutto viene realizzato con una serie di tag LZX che definiscono i componenti dell'interfaccia, la loro posizione, e le loro carattaristiche, il tutto riutilizzabile con la logica della programmazione ad oggetti.
    Per esempio questo codice
    < canvas>
    <button onclick="vw.setWidth(200)">Expand
    Width</button>
    <button x="120"
    onclick="vw.setWidth(100)">Reset</button>
    <view id="vw" y="30" width="100" height="100">
    <!-- onwidth is sent anytime width is changed -->
    <handler name="onwidth">
    this.setAttribute('bgcolor', (this.width
    > 100 ? red : blue));
    </handler>
    </view>
    </canvas>
    permette la creazione di due pulsanti, e relativi eventi.
  • Ci sono a disposizione numerevoli componenti, personalizzabili e riusabili, e le api, lmanoe per quanto riguarda l'implementazione con flash, è ben supportata e testata
Contro
  • Per dare un minimo di interattività alla pagina bisogna comunque utilizzare dell'actionscript, quindi bisogna conoscere questo linguaggio
  • Il supporto DHTML non è ancora maturo... quindi si può produrre stabilmente solo con flash, e quindi ci si lega troppo a questo prodotto




Fonti:
OpenLaszlo White Paper: http://www.openlaszlo.org/whitepaper/LaszloWhitePaper.pdf

venerdì 29 agosto 2008

Gwt-Log

Una delle cose più noiose nel logging con applicazioni GWT è che, lato client, non si riesce ad usare nativamente la console di loggin, ne quella di GWT in Hosted mode, nè quella del server. Il che diventa noioso, poichè spesso si ha la necessita di avere un minimo di tracciabilità delle attività svolte dal codice, e si vuole subito avere un feddback con il loggin, ma con gwt, almeno lato client, sono sempre stato obbligare ad usare i fastidiosi "windows alert".
Certo, da una parte hanno la loro utilità, come quella di bloccare, di fatto, l'esecuzione dell'applicazione e questo può avere un suo aspetto positivo... ma sono troppo invadenti... e soprattutto se ce si li dimentica nel codice, passando poi il prodotto al cliente, si posson avere situazioni imbarazzanti.

Ho trovato, in questi giorni, una libreria davvero interessante per il loggin con GWT


Che gestisce in maniera del tutto trasparente il loggin su più livelli... infatti, lasciando fare tutto a lui (ci sono comunque dei setting da poter usare per disabilitare/abilitare i vari tipi di logger), si può avere il log lato server (anche gli errori lato client possono essere spediti in amniera del tutto trasparente al server con rpc), con la normale console errore del server (errori lato server, come con il normale System.out o System.err), sia nella console dell'Hosted Browser di GWT (come con il classico GWT.log)(client e server), sia un log da leggere con al console di FireBug (un ottima estensione di Fiorefox), sia con un interessante "finestrella div" che compare all'interno delal applicazione stessa, un div semitrasparente draggabile...
Insomma, si può fare veramente di tutto e con in pratica nessuna riga di codice particolare... si importa la libreria nel progetto, si inseriscono alcune righe nel file gwt.xml... e basta usare Log(stringa) e via che si logga dappertutto.
Stupendo.


Aggiornamento: Strani Errori
Ieri sembrava funzionare tutto perfettamente, mentre oggi, aggiornando il progetto a GWT 1.5, cambiando quindi librerie eccetera, ho forse commesso qualche errore... e non si compilava più il modulo gwt... continuava a lamentarsi che non trovava la libreria di gwt-log, in particolare che non trovava il file di confiugurazione gwt.xml del progetto gwt-log
L'errore era:
[echo] Module: com.fdlservizi.sse.HelpDeskGWT
[java] Loading module 'com.fdlservizi.sse.HelpDeskGWT'
[java] Loading inherited module 'com.allen_sauer.gwt.log.gwt-log'
[java] [ERROR] Unable to find 'com/allen_sauer/gwt/log/gwt-log.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?
[java] [ERROR] Line 7: Unexpected exception while processing element 'inherits'
[java] com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
[java] at com.google.gwt.dev.cfg.ModuleDefLoader.nestedLoad(ModuleDefLoader.java:225)
[java] at com.google.gwt.dev.cfg.ModuleDefSchema$BodySchema.__inherits_begin(ModuleDefSchema.java:194)
[...]

Non so per quale motivo, ma ignorava totalmente la presenza della libreria, che invece avevo normalmente selezionato tar le librerie esterne in IntelliJ Idea.
Poi, guardando bene il forum di grails (in particolare questa discussione), non ho capito bene perchè, ho scoperto che dovevo inserire tale libreria nella directory /lib/gwt.
Cosa mai fatta, anche perchè eventualmente le librerie le avrei messe in /lib, dentro al quale la directory gwt non esisteva nemmeno.
Ora invece, con l file messo lì dentro, funziona senza problemi.... misteri di grails.

venerdì 22 agosto 2008

Alcuni problemi con gli id composti e i valori di default con Hibernate

Stamattina, dopo aver passato due giorni a studiarmi il "paradigma di programmazione" per le GUI usato in sap (potrebbe tornarci utili, è uno interessante punto di riferimento a cui potremmo ispirarci), sono tornato a fare qualche esperimento con Hibernate.
In particolare ho continuato a giocare con le select e gli insert con le nostre classi POJO create per ORM.

Ho generato una pagina gsp di esperimento, con alcuni tasti gwt che usano una rpc, che "stimola" sue servizi lato server, uno per la ricerca delle classi (sempre "chiamata") e una per salvarla.
Nessun problema nella ricerca di chiamata, sia con il findall, il list, il find, i criteria, eccetera...
Bhe, in realtà ci sono dei problemi quando nel database ci sono dei null di troppo... ma è un problema correlato a quello che descvrivo qui in seguito.

Infatti nel momento dell'inserimento abbiamo trovati i primi problemi. Essendo il nostro database costruito con delle doppie chiavi primarie (ogni tabella ha un id, nemmeno numerico autoincrementale, come sarebbe meglio fosse, ma come stringa, correlato sempre ad un altro campo presente in ogni tabella "az" che fa riferimento ad una tabella, az), ogni volta che noi abbiamo una chiave esterna, questa chiave esterna è anch'essa costruita con due campi... e anche al tabella a cui facciamo riferimento ha un id primario composto. Questo comporta che nel ricavare i dati di uno di queste colonne, devo fare un doppio passaggio. Nella colonna ricavo l'id delal classe associata, nella quale ricavo poi l'id, che è quello che viee di fatto immagazzinato nella colonna stessa.
Ma all'atto dell'inserimento questo doppio passaggio non funziona. In pratica non riesco a memorizzare i campi se sono chiavi secondarie esterne... e questo ovviamente è un grosso problema. Il fatto è che non tutto il database è costruito in maniera perfetta, per esempio la tabella chiamata non ha riferimenti di chiave secondarie che puntano ad azienda, altre colonne sì... quindi il toll per il reverse enginering è andato un po' in pappa e non riesce a gestire in maniera completa queste doppie chiavi.
Il tutto dovrebbe risolversi attuando una modifica al database che già volevamo attuare, cioè eliminare totalmente tutte le chiavi primarie composte con quel campo az, che di fatto non serve a nulla. Era stato introdotto tempo addietro quando il programma doveva essere multiazienda, cosa che è stata in seguito abbandonata.
Non toglieremo nella tabelle il campo az (presente in tutte) e nemmeno la tabella az (per retrocompatibilità, alcune query presenti qua e là nel programma fanno riferimento a questa colonna), ma modificheremo tutte le chiavi primarie, facendole diventare uniche e non più composte (composte cioè dal solo campo id) e elimineremo ogni chiave secondaria esterna, in ogni tabella, che faccia riferimento ad az.

Stamattina mi sono accorto però di un nuovo problema... la generazione automatica delle classi di dominio POJO, usate da Hibernate, non ha tenuto conto dei valori di default impostati nel database... essendo in sql server sono impostate con delle costraint di questo tipo
ALTER TABLE [dbo].[chiamata] ADD DEFAULT ('N') FOR [libretto]
in questo caso la colonna libretto della tabella chiamata è impostata con un valore di default = N (tra l'alro la colonna ha come proprietà il poter accettare valori null).
In hibernate di fatto non esistono modi per specificare nel file di mapping delle classi i valori di default... esisterebbe ma non è portabile sui vari databasi, prchè bisognerebbe specificare il formato di colonna, diverso per ogni tipologia di database, qundi da evitare.
Di fatto, in una situazione del genere, se si vuole memorizzare nel database una classe di dominio per la quale non si specificano valori per un determinato fields, se questo accetta nel mapping valori null, hibernate lo inizializza automaticamente con null... infatti hibernate, quando deve memorizzare una classe sul database, nella query sql insert, specifica tutti i campi della classe stessa che nella proprietà del mapping abbiano insert=true
Ovviamente, se questa proprietà non viene specificata, hibernate automaticamente le popola con il valore null se la proprietà stessa l'accetta, o con al string avuota nel caso sia specificata not null
Questo significa che di fatto vengono ignorati i valori di default specificati nel database, perchè di fatto al database arriva una query con quei campi specificati... quindi inserisce quelli e non i valori che lui ha come default.
Se per esempio voglio forzare il database ad inserire i valori di dafault, dovrei fare in modo che hibernate non gli passi proprio quel campo... cosa possibile da fare, basta specificare insert=false



facendo così hibernate ignora il campo libretto, e il database, non ricevendolo nella query insert, lo inserisce con il valore di default
Così facendo però non è possibile inserire alcun valore... quindi se io volessi, all'atto della insert, specificare un valore per quella propietà, di fatto questa viene ignorata.

Nel nostro caso, in effetti, c'è un modo molto semplice per risolvere il problema... basta mettere nel costruttore della classe di dominio il valore di default, o nel mio caso, dato che per le classi di dominio che vengono utilizzate anche lato client gwt, devo costruire una determinata classe che viene poi serializzata ed usata nel passaggio dati nella rpc, dichiaro quel dato field con il valore di default, così facendo, anche se lato client non viene specificato alcun valore, di fatto hibernate lo riceve con il valore preimpostato e lo passa al database.

public class DatiChiamata implements IsSerializable {
public String id;
public String apertaDa;
public String tipoChiamata;
public String gradoDisservizio;
[...]
public String noteAssegnazione;
public String libretto = "N";
[...]
}