Modell Alapú Szoftverfejlesztés Eclipse-szel
Miről lesz szó ?
Három Eclipse projekt
1. EMF – Eclipse Modeling Framework
modellközpontú szoftverfejlesztés
2. GEF – Graphical Editing Framework
magas szintű grafikus eszközkészlet
ami a modellben “benne van”, azt nem kell kézzel megírni
pl. “gráf” típusú hálózatoknál mozgatás, kijelölés, összekötés
3. GMF – Graphical Modeling Framework
EMF + GEF szisztematikus összeházasítása
1. Eclipse Modeling Framework (EMF) Előadás anyaga
http://www.eclipse.org/emf/doc/ Modellező Keretrendszer Kód generálása modell alapján, iteratívan Modell relációk betartatásával (számosságok, kétirányú relációk stb.) Adatmodell “szerviz” funkciók mentés/betöltés (XML perzisztencia) Reflexió Dinamikusan módosítható adatmodell Segédletek UI készítéséhez Eclipse “Property Sheet” Változásértesítés (notification)
Mi az a modell?
Adatmodell: Objektumok, attribútumok Relációk Constraint-ek Műveletek tkp. az osztálydiagram
Modellformátum: “annotated Java” .ecore (XML/XMI) Rational Rose
Modell formátumok Book Title: String pages: Int
Annotated Java /** * @model */ public interface Book { /** * @model */ String getTitle();
}
/** * @model */ int getPages();
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" XMI name="library "nsURI="http:///library.ecore" nsPrefix="library"> <eClassifiers xsi:type="ecore:EClass" name="Book"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="title" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> <eStructuralFeatures xsi:type="ecore:EAttribute" name="pages" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
XML Schema
<xsd:schema targetNamespace="http:///library.ecore" xmlns="http:///library.ecore" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:complexType name="Book"> <xsd:sequence> <xsd:element name="title" type="xsd:string"/> <xsd:element name="pages" type="xsd:integer"/>
Generált kód Book Title: String pages: Int
Java implementation public class BookImpl extends EObjectImpl implements Book { ... protected static final int PAGES_EDEFAULT = 0; protected int pages = PAGES_EDEFAULT; public int getPages() { return pages; }
Java interface public interface Book extends EObject { String getTitle(); void setTitle(String value);
}
public void setPages(int newPages) { int oldPages = pages; pages = newPages; if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.SET, ..., oldPages, pages)); }
int getPages(); void setPages(int value);
}
...
Generált kód: relációk, tartalmazás Library Name: String
Library 1
books 0..*
Tartalmazás
}
Book Title: String pages: Int
Writer books 0..*
author 1
Name: String
Kétirányú reláció
public EList getBooks() { if (books == null) { books = new EobjectContainmentEList (Book.class, this, ...); } return books;
public NotificationChain basicSetAuthor(..) { Writer oldAuthor = author; author = newAuthor; if (eNotificationRequired()) { ENotificationImpl notification = new ENotificationImpl(this, ...); if (msgs == null) msgs = notification; else msgs.add(notification); } return msgs;
public void setAuthor(Writer newAuthor) { if (newAuthor != author) { NotificationChain msgs = null; if (author != null) msgs = ((InternalEObject)author). eInverseRemove(this, ..., msgs); if (newAuthor != null) msgs = ((InternalEObject)newAuthor). eInverseAdd(this, ..., msgs); msgs = basicSetAuthor(newAuthor, msgs); if (msgs != null) msgs.dispatch(); } else if (eNotificationRequired()) eNotify(new ENotificationImpl(this, ...)); }
Továbbá... Factories
Használat
public interface LibraryFactory extends EFactory { LibraryFactory eINSTANCE = new LibraryFactoryImpl();
}
LibraryFactory factory = LibraryFactory.eINSTANCE; Book book = factory.createBook();
Book createBook(); Writer createWriter(); Library createLibrary();
Writer writer = factory.createWriter(); writer.setName("William Shakespeare");
LibraryPackage getLibraryPackage();
book.setTitle("King Lear"); book.setAuthor(writer);
A metódus törzseket az Impl osztályokban meg kell írni! Módosítások védelme /** * ... * @generated NOT */ public String getTitle() { // módosítás... return title; }
Értesítés kérése I. Adapter bookObserver = ... book.eAdapters().add(bookObserver);
Értesítés kérése II. EObject someObject = ...; AdapterFactory someAdapterFactory = ...; Object requiredType = ...; if(someAdapterFactory.isFactoryForType(requiredType)) { Adapter theAdapter = someAdapterFactory.adapt(someObject, requiredType); ... }
Valamint... A kódgenerátor intelligens, jól paraméterezhető, és ha kell a sablonok is módosíthatók
Nem említettük: EMF.Edit: további “wrapper” osztályok az Impl. fölé: CommandStack magasszintű modell szerk. Parancsokhoz Eclipse “Property Sheet” + attribútum szerkesztő segédletek eNotification → IViewerNotification ... tkp. részletkérdés, mert elfedhető a GMF-fel EMF.Editor: hibrid grafikus/szöveges “TreeView” editor ... használjuk inkább a GMF-et
2. Graphical Editing Framework (GEF) Előadás anyaga
http://www.eclipse.org/gef/reference/GEF Tutorial 2005.ppt
Eclipse Runtime-ban futó grafikus alkalmazásokat készítő keretrendszer Bővíthető, magas szintű eszköztár a leggyakoribb igényeknek megfelelő funkcionalitás megvalósításával
ui.views
GEF
RCP SWT Platform Runtime
Draw2D
GEF Célkitűzések “Vizualizáció” Modell grafikus megjelenítése “Szerkesztés”: modell-felhasználó “interakció” megteremtése GUI beviteli eszközök (egér, bill.) kezelése, Bevitt input modell szintű értelmezése Parancsok, undo/redo Modell változások kezelése “Integráció” Eclipse környezetbe Menük, billentyűkombinációk, Toolbar-ok, Wizard-ok “Property Sheet” szerkesztő Eclipse integráció: - gazdag “editor/workbench” szemléletű eszközkészletet ad - de csak Eclipse RCP-ben használható
GEF Architektúra
Interaction Layer
Model-to-View mapping
Workbench Integration
Rendering
Layout
Scaling
Native (SWT) Layer
Egyszerű példa, grafikus lehetőségek
2
6
4 5
1
Display d = new Display(); Shell shell = new Shell(d); shell.setLayout(new FillLayout());
2
BorderLayout
1
2
3
4
Bottom
XYLayout
ToolbarLayout
12,8,20,10
Bővíthető “Layout Manager”-ek
5
Top Center
6
FlowLayout
Right
shell.setText(“draw2d”); shell.open(); while (!shell.isDisposed()) while (!d.readAndDispatch()) d.sleep();
3
4
FigureCanvas canvas = new FigureCanvas(shell); canvas.setContents(new Label("Hello World"));
Left
1 2 3 4 5 6 7 8 9 10 11 12
13
Canvas/Figure hierarcha
30,20,27,14
1
2
3
További lehetőségek ●
Koordináta-transzformációk, zoom, “nézetek”
●
Szöveg-megjelenítés: “Rich” text a org.eclipse.draw2d.text-ből ●
●
●
Keretek, színek, sortörés, font-ok, offset API stb... “Label”: text + icon, grafikus elemhez kötötten (pl. “vonal közepe felett”) Labels placed using
Connection: speciális Figure – –
forrás/cél “anchor” Router-ek (pl. Fan, Bendpoint, Manhattan, ShortestPath)
ConnectionLocators
Endpoint v{ Anchor Location
Midpoint
-4
Fig 1
2
PolygonDecoration
1
-1 -2
u
}
–
Fig 2
PolylineConnection -3
-2
-1
Model-View-Controller “Diagram” EditPart
Model Root (Diagram)
fig
Children
…
fig
…
…
fig
A “tartalmazás” reláció tükröződik, de nem feltétlen kell 1-1-1 megfeleltetés (azért nem árt...)
GraphicalViewer Model
EditPart Factory
EditParts
Figures
@#!
EditPart-ok készítése AbstractGraphicalEditPart-ból származtatva: 1. createFigure() - Figure megrajzolása (draw2d/SWT) 2. refreshVisuals() - modell állapotának lekérdezése, grafika frissítése 3. getModelChildren() - megfelelő modell objektum gyermekeinek lekérdezése Az editPart-okat be kell csatolni a modell változás-értesítés mechanizmusába: az editPart felelőssége, hogy intelligensen kitalálja, mely gyermekén kell refreshVisuals()-t hívni (újrarajzolni) GEF objektumok becsatolása EMF “notification” láncba problémás, de megoldható. Automatikus (generált) megoldást majd a GMF ad.
Szerkesztő parancsok életútja EditPart EditPart EditPart EditPart
Tool Tool
EditPolicy EditPolicy EditPolicy EditPolicy
SWT Events Requests Requests
showFeedback()
eraseFeedback()
getCommand()
Commands Commands ?
EditPolicy Request
Stack Stack Commands
Command
EditPart-hoz rendelhető logika
pl. figure anchorPoint-jára kattitva connection mozgató parancs visszaadása
Tool
Több grafikus elemre hivatkozó művelet vezénylő állapotgépe pl. creationTool: Palettából Canvas-ra DnD visszajelzéssel
“Big Picture” EditDomain EditPartViewer EditPartViewer EditPartViewer 1. acts on
Model
2. events 3. request
4. command
Palette
Active Tool
Tool1
CommandStack 5. execute
Command
Tool2
Command
Tool3
Command Command
6. modifies
3. Graphical Modeling Framework (GMF)
EMF + GEF “szisztematikus” összeházasítása
Kiindulás: EMF osztálydiagram
Eredmény: GEF alkalmazás (plugin)
A szükséges kód generálása 50-100%-ban automatikus, wizard-okkal “fél-grafikus” editorokkal támogatott
(Fél)automatikusan generálja azt a “glue” kódot és alkalmazás logikát, amit unalmas lenne megírni Grafikus Eclipse alkalmazások fejlesztésében
Segít ? Nagyon sokat
Korlátoz? Kicsit
GMF fejlesztés menete
Domain Model: class diagram Domain Gen Model: EMF kódgenerátor paraméterek
Graphical Def Model: Figure definíciók (modellek) Tooling Model: GEF “Tool”-ok
Mapping Model: Figure↔Model elem ↔Tool összerendelés Diagram Gen Model: GMF kódgenerátor paraméterek