English (UK)

Continua la serie sulle possibilità offerte dagli ambienti di sviluppo per estendere le proprie funzionalità, con una piccola parentesi non totalmente in tema, ma decisamente interessante per completare quanto detto nel precedente articolo riguardo la stesura di moduli per NetBeans grazie alle sue feature.

Chi di voi non ha pasticciato almeno una volta con le macro di Microsoft Office alzi la mano e faccia un esame di coscienza; tutti gli altri ricorderanno benissimo come da molti anni, grazie alle API della suddetta suite, sia possibile con poche righe di Visual Basic scrivere delle utilissime funzioni per i vari programmi di Office con tanto di editor di GUI e di sorgente — come in una versione Express del Visual Studio — nell'amabile logica di programmazione orientata agli eventi.

Finalmente anche OpenOffice.org dalla versione 2.0.4 e StarOffice — versione estesa e commerciale di OpenOffice.org — come avviene per le varie distribuzioni di editor basate su Eclipse, dalla 8 update 4, ha deciso di offrire le stesse possibilità; chiaramente con il linguaggio di programmazione Java, alla base di OpenOffice.org, ed un interessante modulo per NetBeans: OpenOffice.org API plugin. Pare infatti che questo plug-in permetta, grazie al riconoscimento e all'utilizzo delle API di OpenOffice.org, di ottimizzare la produttività per lo sviluppo delle nuove estensioni (file .oxt) per la suite di office automation.

Sul blog ufficiale di Sun Microsystems troviamo infatti l'interessante tutorial “Developing OpenOffice extensions using Java and NetBeans”, che illustra le operazioni fondamentali per giungere al nostro scopo utilizzando NetBeans 6, il JDK 6, OpenOffice.org 2.0.4 e l'OpenOffice.org SDK. Il tutorial si conclude con un paio di brevi video dimostrativi.

Come segnalato anche nel citato documento, è possibile vedere la presentazione della nuova infrastruttura ad estensioni di OpenOffice.org presentata all'OpenOffice.org Conference o, meglio ancora, leggere sul wiki di OpenOffice.org come sia possibile integrare l'IDE e la suite di office automation prodotti da Sun. Dopo questa parentesi, nel prossimo articolo concluderemo la serie in corso, osservando come sia possibile estendere le funzionalità di un ulteriore ambiente di sviluppo Java-based.

Tratto da programmare.it di Pierpaolo Cira

Come pilotare Rhinoceros dal plug-in
Presento qui i listati dei file .NET del plug-in di base con alcuni comandi funzionanti, presi direttamente dal sito della Mc Neel, in modo da avere qualche esempio su come strutturare l'interfaccia con Rhinoceros.
 
RhinoPlugInBasePlugIn.vb
Public Class RhinoPlugInBasePlugIn Inherits RMA.Rhino.MRhinoUtilityPlugIn
 Public Overrides Function PlugInID() As System.Guid
  Return New System.Guid("{722abf0d-d9d2-4cd7-8637-d9b11148b7ed}")
 End Function

 Public Overrides Function PlugInName() As String
  Return "RhinoPlugInBase"
 End Function

 Public Overrides Function PlugInVersion() As String
  Return "1.0.0.0"
 End Function

 Public Overrides Function OnLoadPlugIn() As Integer
  '''<returns>        
  '''  1 = initialization succeeded, let the plug-in load   
  '''  0 = unable to initialize, don't load plug-in and display an error dialog  
  ''' -1 = unable to initialize, don't load plug-in and do not display an error  
  '''      dialog. Note: OnUnloadPlugIn will not be called       
  '''</returns>    
  Return 1
 End Function

 Public Overrides Sub OnUnloadPlugIn()
 End Sub
End Class
RhinoPlugInBasePlugInAttributes.vb 
Public Class MyPlugIn1Attributes Inherits RMA.Rhino.MRhinoPlugInAttributes
 Public Overrides Function Address() As String
  Return "undefined"
 End Function

 Public Overrides Function Country() As String
  Return "Italy"
 End Function

 Public Overrides Function Email() As String
  Return "Questo indirizzo email è protetto dagli spambots. È necessario abilitare JavaScript per vederlo."
 End Function

 Public Overrides Function Fax() As String
  Return "undefined"
 End Function

 Public Overrides Function Organization() As String
  Return "Tessaro Bruno"
 End Function

 Public Overrides Function Phone() As String
  Return "undefined"
 End Function

 Public Overrides Function UpdateURL() As String
  Return "undefined"
 End Function

 Public Overrides Function Website() As String
  Return "undefined"
 End Function
End Class
AddLayerCommand.vb 
Imports RMA.Rhino Imports RMA.OpenNURBS Imports RMA.Rhino.RhUtil

Public Class AddLayerCommand Inherits RMA.Rhino.MRhinoCommand
 Public Overrides Function CommandUUID() As System.Guid
  Return New Guid("{fe405805-c87d-4445-a48c-6a15a6c70817}")
 End Function

 Public Overrides Function EnglishCommandName() As String
  Return "AddLayerCommand"
 End Function

 Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result
  Dim layer_table As MRhinoLayerTable = context.m_doc.m_layer_table
  Dim unused_name As String = ""
  layer_table.GetUnusedLayerName(unused_name)

  Dim gs As New MRhinoGetString()
  gs.SetCommandPrompt("Name of layer to add")
  gs.SetDefaultString(unused_name)
  gs.AcceptNothing(True)
  gs.GetString()
  If (gs.CommandResult() <> IRhinoCommand.result.success) Then
   Return gs.CommandResult()
  End If

  Dim layer_name As String = gs.String()
  layer_name = layer_name.Trim()
  If (String.IsNullOrEmpty(layer_name)) Then
   RhUtil.RhinoApp().Print("Layer name cannot be blank." + vbCrLf)
   Return IRhinoCommand.result.cancel
  End If

  If (RhUtil.RhinoIsValidName(layer_name) = 0) Then
   RhUtil.RhinoApp().Print(layer_name + " is not a valid layer name." + vbCrLf)
   Return IRhinoCommand.result.cancel
  End If

  Dim layer_index As Integer = layer_table.FindLayer(layer_name)
  If (layer_index >= 0) Then
   Dim msg As String = "A layer with the name " + layer_name + " already exists." + vbCrLf
   RhUtil.RhinoApp().Print(msg)
   Return IRhinoCommand.result.cancel
  End If

  Dim layer As New OnLayer()
  layer.SetLayerName(layer_name)
  layer_index = layer_table.AddLayer(layer)
  If (layer_index < 0) Then
   RhUtil.RhinoApp().Print(String.Format("Unable to add {0} layer." + vbCrLf, layer_name))
   Return IRhinoCommand.result.failure
  End If
  Return IRhinoCommand.result.success
 End Function
End Class 
ExtendSurfaceCommand.vb 
Imports RMA.Rhino Imports RMA.OpenNURBS Imports RMA.Rhino.RhUtil

Public Class ExtendSurfaceCommand Inherits RMA.Rhino.MRhinoCommand
 Public Overrides Function CommandUUID() As System.Guid
  Return New Guid("{1120623a-268f-4986-a9e5-dd287763159c}")
 End Function

 Public Overrides Function EnglishCommandName() As String
  Return "ExtendSurfaceCommand"
 End Function

 Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result
  Dim go As New MRhinoGetObject
  go.SetCommandPrompt("Select edge of surface to extend")
  go.SetGeometryFilter(IRhinoGetObject.GEOMETRY_TYPE_FILTER.edge_object)
  go.SetGeometryAttributeFilter(IRhinoGetObject.GEOMETRY_ATTRIBUTE_FILTER.edge_curve)
  go.GetObjects(1, 1)
  If (go.CommandResult() <> IRhinoCommand.result.success) Then
   Return go.CommandResult()
  End If

  Dim objref As IRhinoObjRef = go.Object(0)
  Dim srf As IOnSurface = objref.Surface()
  If (srf Is Nothing) Then

   RhUtil.RhinoApp().Print("Unable to extend polysurfaces." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  Dim brep As IOnBrep = objref.Brep()
  Dim face As IOnBrepFace = objref.Face()
  If (brep Is Nothing Or face Is Nothing) Then Return IRhinoCommand.result.failure
  If (face.m_face_index < 0) Then Return IRhinoCommand.result.failure

  If (Not brep.IsSurface()) Then
   RhUtil.RhinoApp().Print("Unable to extend trimmed surfaces." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  Dim trim As IOnBrepTrim = objref.Trim()
  If (trim Is Nothing) Then Return IRhinoCommand.result.failure

  Dim edge_index As IOnSurface.ISO = trim.m_iso
  Dim dir As Integer = edge_index Mod 2
  If (srf.IsClosed(1 - dir)) Then
   RhUtil.RhinoApp().Print("Unable to extend surface at seam." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  If (edge_index < IOnSurface.ISO.W_iso Or edge_index > IOnSurface.ISO.N_iso) Then
   RhUtil.RhinoApp().Print("Selected edge must be an underlying surface edge." + vbCrLf)
   Return IRhinoCommand.result.nothing
  End If

  Dim myface As OnSurface = srf.DuplicateSurface()
  If (myface Is Nothing) Then
   Return IRhinoCommand.result.failure
  End If

  Dim rc As Boolean = RhUtil.RhinoExtendSurface(myface, edge_index, 5.0, True)
  If (rc) Then
   Dim mybrep As New OnBrep()
   mybrep.Create(myface)
   Dim obj As New MRhinoBrepObject()
   obj.SetBrep(mybrep)
   context.m_doc.ReplaceObject(New MRhinoObjRef(objref.Object()), obj)
   context.m_doc.Redraw()
  End If
  Return IRhinoCommand.result.success
 End Function
End Class 
LanguageCommand.vb 
Imports RMA.Rhino Imports RMA.OpenNURBS Imports RMA.Rhino.RhUtil

Public Class LanguageCommand Inherits RMA.Rhino.MRhinoCommand
 Public Overrides Function CommandUUID() As System.Guid
  Return New Guid("{d8dda157-454c-4e9b-a740-7df8815fe100}")
 End Function

 Public Overrides Function EnglishCommandName() As String
  Return "LanguageCommand"
 End Function

 Public Overrides Function RunCommand(ByVal context As RMA.Rhino.IRhinoCommandContext) As RMA.Rhino.IRhinoCommand.result         Dim settings As MRhinoAppSettings = RhUtil.RhinoApp.AppSettings      
  Dim appearance As IRhinoAppAppearanceSettings = settings.AppearanceSettings()
  Dim id As Integer = CType(appearance.m_language_identifier, Integer)
  Dim culture As New System.Globalization.CultureInfo(id)
  RhUtil.RhinoApp.Print("The current language is " + culture.EnglishName + vbCrLf)
  Return IRhinoCommand.result.success
 End Function
End Class 
Si possono cercare nella guida di riferimento gli altri comandi impiegabili nei plug-in. Il resto è la classica programmazione in Visual Basic .NET. Non sto qui a pubblicare una guida a tale linguaggio, in rete ne esistono già di ottime.

Analizziamo il plug in di base generato dal wizard per studiare la struttura di base di un plug-in per Rhino.

File: nomepluginAttributes.vb Qui sono salvate le stringhe con i dati dello sviluppatore del plug-in e del plug-in stesso

File: nomepluginPlugIn.vb Class PlugInID (identificatore unico del plug-in) Function PlugInName (nome) Function PlugInVersion (versione) Function OnLoadPlugIn (codice da eseguire all'avvio del plug-in) Function OnUnloadPlugIn (codice da eseguire alla chiusura del plug-in) Function OnDisplayPlugInHelp (aiuto plug-in)

File: nomepluginCommand.vb Function CommandUUID (identificatore unico del comando) Function EnglishCommandName (nome comando da digitare sulla command bar e uguale a nome file vb) Function RunCommand (codice del comando da eseguire)

Per aggiungere altri comandi con il corretto UUID usare il menu: Progetto -> Aggiungi nuovo elemento -> Rhino command

Per un'eventuale integrazione e uso di database SQL su file Access .mdb Per poter disporre di un database SQL nell'applicazione si può usare il seguente driver di .NET Framework: Microsoft Jet OLEDB 4.0 E' integrato in .NET Framework e lavora su file MDB: Dati -> Aggiungi nuova origine dati Nuova connessione Origine dati: File di database Microsoft Access (OLE DB) Nome di file di database: ...file.mdb

Vediamo com'è strutturato un plug-in e come muovere i primi passi. Aprire Visual Basic 2005 Express. Scegliamo la voce Crea progetto e quindi il template Rhino Plug-in. Attendere il caricamento del wizard.

Scegliere il nome del progetto. Plug-in type: General Utility Plug-in. Scegliere: Add this plug-in to the help menu. Premere sul bottone Next. Inserire le info dello sviluppatore. Premere sul bottone Finish.

Si ottiene un progetto plug-in di base pronto.

Ora possiamo scrivere tutto il codice sorgente necessario alla nostra extension. Per ora non scriviamo nulla, vediamo direttamente cosa fare al termine del lavoro.

Scegliere il menu Genera e generare il progetto. Avviare Rhinoceros 4.0 selezionare il menù: Strumenti -> Opzioni (ovvero Tools -> Options). Aprire la sezione Plug-ins. Premere il pulsante Install. Scegliere la dll creata da VBasic che si trova nella cartella:  Documenti\Visual Studio 2005\Projects\ProjectName\bin\Release La plug-in è ora correttamente installata su Rhinoceros 4.0 ed è utilizzabile richiamando i comandi.

A venirci incontro è un interessante tutorial di Nathan A. Good presente sul developerWorks di IBM: Build extensions for Eclipse one snippet at a time.

Considerato che le funzionalità dei plug-in da scrivere sono algoritmi che dipendono esclusivamente dallo sviluppatore e dagli scopi da raggiungere, indipendentemente dalla piattaforma da utilizzare, l'unica parte che ci interessa realmente è relativa alla presentazione vera e propria dei nostri dati, insomma le interfacce.

Il core di Eclipse è strutturato veramente bene in un'ottica orientata oggetti, dato che abbiamo una grande ed ordinata gerarchia di classi: tramite file XML dobbiamo indicare al core quali interfacce (intese nello spirito dell'OOP) utilizzare. Saremo noi poi a decidere se implementarle da zero, estendendo una classe astratta o utilizzando direttamente una classe ad hoc tra quelle messe a disposizione.

Esistono classi per gliscopi più disparati: dalle azioni dei pulsanti, alle voci dei menu contestuali, alle viste della GUI, agli editor testuali e così via. Sebbene sarebbe tutto, grazie sia ai nomi che alla documentazione, molto intuitivo, un tutorial risulta utile in quanto non è semplicissimo sapere quale classe bisogna utilizzare per i propri scopi, visto l'enorme labirinto di funzioni messe a disposizione che, in questo caso, funge da lato oscuro della medaglia.

Se non si ha la voglia di comprare un testo a riguardo, tenuto conto che non c'è una grande scelta, o non si ha tempo di leggerlo, il tutorial summenzionato cade a proposito. Esso copre, infatti, in modo abbastanza dettagliato i passi necessari per utilizzare interfacce e classi del core di Eclipse per creare plugin o estendere funzionalità, trattando interessanti topic come viste, azioni, preferenze, wizard e così via.

Il tutorial è scritto per Eclipse 3.2 e presuppone una certa conoscenza della programmazione, ma non presenta nulla di assolutamente difficile. Chiaramente, riprendendo quanto detto nel precedente articolo riguardo le varie distribuzioni basate su Eclipse, c'è da ricordare che essendo scritto per la versione 3.2 del core, il tutorial può essere eseguito su tutte le distribuzioni basate su questa versione, incluso IBM Rational Application Developer V7.

McNeel Rhinoceros 4.0 oltre ad essere quell'ottimo prodotto di modellazione che è, permette di integrare se stesso con funzioni aggiuntive create a parte per mezzo di plug-ins scritte in .NET.
Per creare il proprio plug-in innanzitutto bisogna preparare il corretto ambiente di sviluppo.
Teniamo conto che, escludendo Windows XP e Rhinoceros 4.0, tutto il restante software è gratuito.

Partiamo da un sistema Ms Windows XP SP2
Installiamo Windows Installer 3.1
Installiamo McNeel Rhinoceros 4.0
Con questo abbiamo il pacchetto di modellazione correttamente installato.

Proseguiamo con l'ambiente di sviluppo. Installiamo:
.NET Framework 2.0
.NET Framework 2.0 Language Pack (italian)
Ms Visual Basic 2005 Express (oppure il pacchetto open source Sharp Develop 2.2)
Ms Office Access Runtime 2007 (solo per creare file .mdb di partenza da ODBC se servono)
Rhino 4 SDK

Scarichiamo dal sito www.rhino3d.com il file Rhino4DotNetWizards.zip
Dal file copiare RMA.VisualStudioWizards.dll in C:\WINDOWS\assembly
ed eseguire Rhino4DotNetWizards.vsi
Copiare Rhino_DOTNET.xml nella cartella di rhino4.exe per avere una guida dei comandi a disposizione.

L'ambiente di sviluppo è pronto.

Il primo ambiente di sviluppo che prendiamo in esame non può che essere Eclipse e il suo PDE (Plugin Development Environment). Come dice anche il nome, Eclipse stesso non è altro che un ambiente per lo sviluppo di plug-in per la propria piattaforma; l'unione poi del framework di base con determinati plug-in fa sì che si possa avere l'ambiente di sviluppo desiderato.

È per questo che esistono varie distribuzioni ufficiali di Eclipse sul suo sito: quella per scrivere applicazioni Java, quella per applicazioni Web con Java, quella per applicazioni C/C++ e così via; si tratta dello stesso core su cui sono connessi plug-in differenti in base agli scopi da raggiungere.

Alla base di questo core esistono poi editor come IBM Rational Application Developer: nello specifico si tratta del core di Eclipse (più alcuni dei plug-in della distribuzione base) cui IBM ha agganciato dei plug-in proprietari e commerciali di propria produzione in una distribuzione esclusivamente commerciale. Quindi sommariamente, quando si usa ad esempio la distribuzione base di Eclipse, non si sta facendo altro che utilizzare il core più vari plug-in necessari, ai quali si possono aggiungere altri plug-in per estendere le funzionalità.

Sta allo sviluppatore decidere se il plug-in che sta sviluppando è pensato per essere integrato in una distribuzione esistente o in una distribuzione ad hoc; è così che nascono e crescono progetti come PHPEclipse — per la scrittura di codice PHP con Eclipse — o SBeaVeR, per la scrittura di vocabolari e regole di business secondo lo standard SBVR di OMG.

Un'altra cosa fondamentale è che Eclipse, dalla versione 3.0, è compatibile con l'OSGi framework, implementandone le specifiche e quindi aumentando la portabilità grazie a questo nuovo modello basato sui componenti.

Per uno sviluppatore Java, Eclipse è senza dubbio uno dei migiori ambienti di sviluppo. Ma questo ambiente sta crescendo sempre più e nasconde molte doti nascoste anche al di fuori di java...

Riporto pari pari, quanto scritto su programmazione.it da Pierpaolo Cira.
 
All'inizio erano all'interno di schede di cartoncino perforate, poi di circuiti non riscrivibili, poi iniziarono ad essere presenti in memorie di tipo magnetico sempre più piccole, capaci e veloci: parliamo dei software e di come, in meno di un secolo, il loro modo di presentarsi all'utente finale sia decisamente cambiato con un'accelerazione a carattere esponenziale.

Ma, oltre all’aspetto con cui i software si presentano, è cambiato anche il modo con cui essi vengono prodotti: dalla macchina perforatrice si è passati a poter inserire i dati da tastiera e, anziché sotto forma di buchi (o di 0 e 1), le istruzioni vengono codificate prima in linguaggio Assembly e poi nei primi linguaggi compilati, sempre più comodi da interpretare e rivedere da parte dei programmatori.

Insieme all'evoluzione dei linguaggi, c'è stata una corrispondente crescita dei metodi per la progettazione e l'ingegnerizzazione del software, ma ancora più importanti potrebbero essere, per alcuni, gli strumenti per la scrittura del codice: gli ambienti integrati di sviluppo o, meno formalmente, gli IDE.

Mi sono permesso di dire che per alcuni lo strumento di creazione del software possa essere più importante della progettazione stessa, visti i sempre maggiori consensi per metodologie di sviluppo agile come l'Extreme programming e considerate anche le notevoli feature messe a disposizione da IDE come Visual Studio, che tendono a nascondere allo sviluppatore gran parte della logica e delle funzioni di basso livello in modo da aumentare la produttività a scapito di codice bacato, che potrebbe scrivere l'utente e che, invece, viene direttamente scritto dall'IDE stesso.

Senza entrare nel dettaglio dei pro e dei contro di questa affermazione, è stupefacente pensare come dai primi IDE creati meno di cinquant'anni fa, che permettevano esclusivamente di scrivere codice, si è passati agli abbandonati, ma storici compilatori con interfaccia a caratteri della Borland; si è poi giunti agli attuali strumenti di sviluppo che — oltre a contenere disparati editor per il codice sorgente dalle illimitate funzioni atte a facilitare lo sviluppatore — contengono compilatori, interpreti, debugger e spesso vengono snobbati se non sono di tipo RAD.

Una tra le ultime interessanti frontiere di questi ambienti di sviluppo è che essi sono progettati per fornire agli sviluppatori la possibilità di estenderli dall'interno: un ecosistema in cui, tramite un IDE, è possibile sviluppare funzionalità per l'IDE stesso e distribuirle sotto forma di plug-in, in modo che altri utenti dello stesso ambiente possano utilizzare le nuove funzioni.

Tratto da Wikipedia, l'enciclopedia libera.

La programmazione in Java è una specializzazione della programmazione con linguaggi orientati agli oggetti.

Il linguaggio Java è un linguaggio orientato agli oggetti con una sintassi simile al linguaggio C e al linguaggio C++. Allo sviluppatore già esperto di programmazione OO, alcuni punti dovrebbero essere evidenziati:

  • Java supporta solo la singola ereditarietà di classi, ma permette l'ereditarietà multipla di interfacce.
  • Java ha una libreria di classi molto grande (detta Java API) simile a SmallTalk, e supporta molte caratteristiche, dai contenitori di oggetti a complesse esigenze di sicurezza. 
  • Java viene eseguito attraverso una Virtual Machine 
  • L'apprendimento del linguaggio non è difficile. La vastità delle "librerie" (o più correttamente package) standard del linguaggio è tale da renderne praticamente impossibile la "padronanza"; per programmare in Java è dunque necessario avere a disposizione la documentazione delle API del linguaggio, disponibile in linea sul sito ufficiale http://java.sun.com/reference/api/index.html.

Un buon punto di partenza per imparare Java è il tutorial di Sun http://java.sun.com/docs/books/tutorial/.

Per sviluppare programmi in Java è teoricamente sufficiente un qualsiasi editor di testo; in pratica, se si vuole scrivere qualcosa di più del classico hello world, occorre un ambiente di sviluppo integrato. Esistono diversi IDE (Integrated Development Environment, ambiente di sviluppo integrato), alcuni gratuiti ed altri a pagamento.

Fra questi quello più premiato è IntelliJ IDEA vincitore fra l'altro del premio Best Java IDE 2005 rilasciato da JDJ. Si tratta di un IDE completo, molto funzionale ed in grado di garantire una padronanza completa del codice che si sta sviluppando.

Un ambiente di sviluppo per Java gratuito e soprattutto leggero è BlueJ, di chiara impostazione didattica, e disponibile per tutti i sistemi operativi al sito gratuito http://www.bluej.org/. Un altro ambiente per lo sviluppo in Java (e non solo) è Eclipse, donato alla comunità di sviluppatori da IBM e scaricabile dalla pagina http://www.eclipse.org. Eclipse è più avanzato e potente, è libero e disponibile per molti sistemi operativi; da notare che quest'ultimo è strutturato con un'architettura a plugin che permette l'aggiunta di ulteriori funzionalità semplicemente scaricando ed installando il relativo plugin.

La Sun stessa ha promosso lo sviluppo di un ambiente di sviluppo gratuito e open source chiamato NetBeans e lo mette a disposizione gratuitamente insieme a Sun Java Studio. Questi due ambienti sono scritti in Java e NetBeans è distribuito (opzionalmente) insieme alla macchina virtuale. Come entità separata, NetBeans è scaricabile da netbeans.org. Uno degli IDE commerciali più diffusi è JBuilder prodotto dalla Borland.