NetBeans platforma Aplikační programování v Javě (BI-APJ) - 7 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti
Architektura NetBeans platformy Netbeans platforma je modulární systém umožňující vytváření rozsáhlých desktopových aplikací systematickým způsobem. Definuje formát modulů a nabízí řadu hotových modulů použitelných pro tvorbu vlastní aplikace. Platforma se skládá z: definice formátu modulu, runtime kontejneru - minimální sada modulů umožňujících běh modulární (negrafické) aplikace, modulů podporujících grafickou aplikaci: Nodes API, Explorer API, Window System API - : moduly pro podporu Javy. NetBeans IDE je jedna z aplikací vytvořená na NetBeans platformě.
NetBeans Modul Základní část, ze které se skládá aplikace na NetBeans platformě. Moduly: umožňují, aby aplikace byla dynamicky (tj. i za běhu) rozšiřována o další funkcionalitu, mohou být tvořeny samostatnou třídou nebo mnoha balíky, poskytují si navzájem služby, definují závislosti, ohraničují viditelnost. Typy modulů: Regular - standardní modul, typicky obsahuje funkcionalitu dostupnou uživatelem (akce v menu). Autoload - moduly, které jsou zaváděny pouze, pokud je jiný modul potřebuje, Eager - moduly, které jsou zaváděny pouze tehdy, pokud jsou splněny jejich závislosti.
Struktura modulu Modul je tvořen souborem.jar obsahujícím: manifest.mf layer.xml class soubory resource soubory konfiguračním souborem: <?xml version="1.0" encoding="utf-8"?> <module name="library.presentation"> <param name="autoload">false</param> <param name="eager">false</param> <param name="enabled">true</param> <param name="jar">modules/library-presentation.jar</param> <param name="reloadable">false</param> </module>
Manifest modulu Souboru manifest.mf je jediná povinná část modulu. Definuje hodnoty atributů např: OpenIDE-Module - jednoznačné jméno modulu (jediný povinný atribut), OpenIDE-Module-Layer - cesta k layer souboru, OpenIDE-Module-Specification-Version - verze modulu v Dewey dekadickém formátu, Příklad: Manifest-Version: 1.0 OpenIDE-Module: libray.model OpenIDE-Module-Localizing-Bundle: libray/model/bundle.properties OpenIDE-Module-Specification-Version: 1.0
Runtime kontejner (1/2) Je tvořen minimální sadou modulů umožňujích běh modulární (negrafické) aplikace:
Runtime kontejner (2/2) Bootstrap - umí zavádět moduly. Startup - obsahuje vstupní bod aplikace (main) a incializační algoritmus. File System API - poskytuje aplikaci přístup do virtuálních souborových systémů. Module System API - umožňuje řídit životní cyklus modulů v aplikaci. Utilities API - kromě jiného obsahuje Lookup API, které umožňuje vyhledávat služby, které si moduly navzájem poskytují.
File System API File System API umožňuje instalovat v aplikaci různé virtuální filesystémy, a tak přistupovat k "souborům" jednotným způsobem bez ohledu na implementaci virtuálního systému. Virtuální filesystém může být: skutečný lokální souborový systém,.jar resp.zip soubor, jakákoliv hierarchická struktura obsahující sekvenční data. "Soubor" i "adresář" virtuálního filesystému je reprezetován objektem FileObject. Virtuální filesystém tvoří jmenný prostor objektů FileObject (jsou určeny cestou). Objekty FileObject jsou zobecněním objektů java.io.file (umožňují např. instalovat posluchače změn "souboru"). Jedním z druhů souboru ve filesystému je tzv. soubor. instance, který reprezentuje serializovaný objekt.
System Filesystem (1/2) System Filesystem je speciální virtuální filesystém obsahující konfigurační data NetBeans aplikace. Každý modul může deklarovat adresáře a soubory v tomto filesystému pomocí souborů layer.xml: <filesystem> <folder name="actions"> <file name="openaddreaderdialogaction.instance"> </folder> </filesystem> Výsledný souborový systém aplikace vzniká sjednocením layer.xml souborů ze všech modulů aplikace. System Filesystem je namapován na podadresář config/ v uživatelském adresáři, kde jsou ukládány všechny změny (System Filesystem je read-write). Adresáře virtuálního souborového systému tvoří tzv. body rozšíření (extension point) aplikace.
System Filesystem (2/2) Některé adresáře jsou definovány v modulech, které jsou částí NetBeans platformy a mají speciální význam: Services/ - adresář pro registraci služeb, které modul poskytuje, Actions/ - adresář globálních akcí. Akce je typicky tvořena souborem.instance, který reprezentuje objekt (singleton) třídy implementující ActionListener. Menu/ - obsah menu bar hlavního okna. Podadresáře reprezentují jednotlivá menu, jejich podadresáře reprezentují submenu atd. Akce jsou reprezentovány soubory typu.instance. Loaders/ - obsahuje podadresáře definující mime types (např.. Loaders/text/x-java)
Lookup API (1/1) Lookup - realizace paternu dependency injection. Objekt lookup umožňuje vyhledávat služby, které v aplikaci zaregistroval některý modul (služba je obvykle realizována singletonem). Default lookup - instance třídy Lookup získaná voláním Lookup.getDefault (), která provádí vlastní hledání metodou lookup. Parametrem hledání je rozhraní (resp. abstraktní třída) služby. Příklad: nalezení služby, která zobrazuje uživateli informační správu (notification): NotifyDescriptor nd = new NotifyDescriptor.Message("Hello...", NotifyDescriptor.INFORMATION_MESSAGE); Lookup defaultlookup = Lookup.getDefault(); DialogDisplayer dd = (DialogDisplayer) defaultlookup.lookup(dialogdisplayer.class) dd.notify(nd);
Lookup API (1/2) Obvykle má abstraktních třída definující službu svou vlastní metodu getdefault implementovanou jako veřejnou statickou metodu: package p; public abstract class MyService { } public static MyService getdefault () { Lookup lkp = Lookup.getDefault(); MyService result =(MyService)lkp.lookup(MyService.class); if (result == null) { result = new TrivialImplementationOfMyService(); } return result; } public abstract void dosomething (...);
Lookup API (1/3) Moduly mohou registrovat objekty poskytující služby třemi způsoby: prostřednictvím standardního Java mechanismu rozšíření - viz třída ServiceLoader, umístěním souboru.instance v adresáři Services v System Filesystem: <folder name="services"> <file name="myservice.instance"> <attr name="instanceclass" stringvalue="p.myserviceimpl"/> <attr name="instanceof" stringvalue="p.myservice"/> </file></folder> anotací: package p; @ServiceProvider(service=MyService.class) public class MyServiceImpl extends MyService {...