Sidst opdateret: 18. juni 2007
Dette øveprogram er en trinvis beskrivelse af, hvordan du opretter en EMF-model og genererer en enkel modeleditor til den. Øveprogrammet viser, hvor let det er at gå fra en enkel modeldefinition til en fuldt funktionsdygtig editor til modellen ved at bruge EMF.
Den model, der vil blive genereret, ser sådan ud i UML (i Oversigt over Eclipse Modeling Framework findes en beskrivelse af modellen):
Vi vil vise, hvordan en EMF-model kan genereres fra to forskellige kilder: En Rational Rose-model eller et sæt annoterede Java-grænseflader og -klasser.
Skærmbillederne er fra version 3.3.0 RC4 af Eclipse SDK og version 2.3.0 RC3 af EMF.
Trin 0: | Forudsætninger |
Trin 1: | Importér modellen fra Rose eller Definér modellen ved hjælp af annoteret Java |
Trin 2: | Generér EMF-modelkoden |
Trin 3: | Generér en editor til modellen |
Trin 4: | Udfør den genererede editor |
EMF Runtime-pakken indeholder EMF-generatoren og et antal relaterede plugins. Kontrollér, at komponenterne findes i dit Eclipse-miljø, når du har installeret pakken:
Der kræves ikke yderligere EMF-plugins til dette øveprogram. Der kan blive vist yderligere plugins, afhængigt af hvilke EMF-pakker du har installeret.
Rose-filen til Library-modellen findes her: library.mdl. Gemt den et sted på din arbejdsstation.
Opret et nyt EMF-projekt i arbejdsområdet:
I stedet for at importere modellen fra et Rose-diagram kan vi starte med et sæt Java-grænseflader og -klasser, som svarer til henholdsvis klasserne og de enumererede typer i library-modellen. Denne kode er det, der kræves som minimum for at illustrere de ønskede funktioner. På dette grundlag konstrueres en Ecore-model og en generator-model, som derefter styrer genereringen af den resterende kode. Koden annoteres med "@model"-koder i Javadoc-kommentarer for at angive eventuelle ikke-standardværdier for Ecore-objekternes attributter og referencer.
Fra EMF 2.3 kan du definere annoterede Java-grænseflader med generiske typer og enumerationer i Java 5.0. Vi vil vise begge fremgangsmåder, når det er relevant. Hvis du vil bruge Java 5.0, skal du sørge for, at værdien for "Java/Compiler/Kompatibilitetsniveau for compiler" i Eclipse er angivet til "5.0" eller derover.
Her er de grænseflader, der beskriver library-modellen:
Library.java (Java 1.4)
package org.eclipse.example.library; import java.util.List; /** * @model */ public interface Library { /** * @model */ String getName(); /** * @model type="Writer" containment="true" */ List getWriters(); /** * @model type="Book" containment="true" */ List getBooks(); }Library.java (Java 5.0)
package org.eclipse.example.library; import java.util.List; /** * @model */ public interface Library { /** * @model */ String getName(); /** * @model containment="true" */ List<Writer> getWriters(); /** * @model containment="true" */ List<Book> getBooks(); }Book.java
package org.eclipse.example.library; /** * @model */ public interface Book { /** * @model */ String getTitle(); /** * @model default="100" */ int getPages(); /** * @model */ BookCategory getCategory(); /** * @model opposite="books" */ Writer getAuthor(); }Writer.java (Java 1.4)
package org.eclipse.example.library; /** * @model */ public interface Writer { /** * @model */ String getName(); /** * @model type="Book" opposite="author" */ java.util.List getBooks(); }Writer.java (Java 5.0)
package org.eclipse.example.library; /** * @model */ public interface Writer { /** * @model */ String getName(); /** * @model opposite="author" */ java.util.List<Book> getBooks(); }BookCategory.java (Java 1.4)
package org.eclipse.example.library; /** * @model */ public class BookCategory { /** * @model name="Mystery" */ public static final int MYSTERY = 0; /** * @model name="ScienceFiction" */ public static final int SCIENCE_FICTION = 1; /** * @model name="Biography" */ public static final int BIOGRAPHY = 2; }BookCategory.java (Java 5.0)
package org.eclipse.example.library; /** * @model */ public enum BookCategory { /** * @model name="Mystery" */ MYSTERY, /** * @model name="ScienceFiction" */ SCIENCE_FICTION, /** * @model name="Biography" */ BIOGRAPHY; }
Opret et nyt, tomt EMF-projekt i arbejdsområdet:
Opret den første Java-grænseflade:
Opret de to andre grænseflader (Book.java og Writer.java) og klassen (BookCategory.java) på samme måde. Når du vil oprette klassen, skal du selvfølgelig vælge "Ny/Klasse" på pop op-menuen i stedet for "Ny/grænseflade".
I generatormodellen vises et rodobjekt, der repræsenterer hele modellen. Dette modelobjekt har underordnede, der repræsenterer dens pakker, og pakkernes underordnede repræsenterer klassifikationer (klasser og datatyper, herunder enumererede typer). Klassernes underordnede er klasseattributter, referencer og funktioner. De underordnede for enumererede typer er enum-strengværdier.
I de fleste tilfælde er det ikke nødvendigt at ændre egenskabernes standardværdi, men indstillingerne giver stor kontrol over den kode, der genereres. En af de indstillinger, der er værd at nævne, er nr. 2 på billedet ovenfor, "Kompatibilitetsniveau". Hvis du vælger at udnytte de nye konstruktioner, der blev indført med Java 5.0 på annoterede Java-grænseflader, eller hvis du vil generere kode, som anvender generiske typer, skal du sørge for, at indstillingen tildeles værdien "5.0" eller derover. Startværdien er baseret på egenskaben Kompatibilitetsniveau for compiler, som er illustreret ovenfor i trin 0.
Generatormodellen er også det sted, du skal starte kodegenereringen fra. Ved at højreklikke på et objekt i modellen kan du generere kode til det.
Efter genereringen vil der være oprettet klassegrænseflader og en enum-klasse (hvis modellen blev importeret fra Rose), eller de vil være færdiggjort (hvis modellen blev defineret ved hjælp af annoteret Java), og der vil være oprettet et nyt sæt grænseflader til pakken selv og til fabrikken. Der vil også være to nye pakker med suffikset "impl" og "util", som indeholder implementeringer af grænsefladerne og funktionsklasserne, og begge typer manifestfiler til model-plugin'en: "plugin.xml" og "MANIFEST.MF".
Hvis du definerede modellen ved hjælp af annoteret Java, får du vist en advarsel i oversigten Problemer: "Importen java.util.List bruges aldrig". Denne advarsel forventes og forhindrer dig ikke i at fortsætte med næste trin.
Hvis du ændrer modellen, kan du generere den igen, og ændringerne flettes samen med eventuelle manuelle ændringer, der kan være foretaget af koden. Du kan også selektivt generere en del af modelkoden ved at højreklikke på en pakke, en klasse eller et enum-objekt og vælge "Generér modelkode" på pop op-menuen.
Der kan også genereres en fuldt funktionsdygtig Eclipse-editor til en hvilken som helst model. Standardværdien er, at den er fordelt på to plugins: en redigering-plugin indeholder adaptere, der leverer en struktureret oversigt og udfører kommandobaseret redigering af modelobjektet, og en editor-plugin leverer brugergrænsefladen til editoren og guiden.
Generelt gælder, at hvis du vil generere plugins til model, redigering og editor på én gang, kan du gøre det ved at vælge "Generér alle" på pop op-menuen.
Derved oprettes også en test-plugin, der indeholder JUnit-testskeletter til test af eventuelle volatile funktioner og operationer, der er defineret i modellen. Denne model indeholder ikke nogen, men du vil normalt selv skulle udfylde indholdet i disse test. Test-plugin'en indeholder også en simpel eksempelklasse, som viser, hvordan du kan indlæse og validere en model i et enkeltstående program.
Koden skulle automatisk blive kompileret under genereringen og bør blive kompileret igen, hver gang den ændres. Hvis du har deaktiveret automatisk bygning i indstillingerne for arbejdsbænken, kan du starte kompileringen manuelt:
Når du vil teste de nye plugins, skal du starte en forekomst mere af Eclipse. Disse plugins skal udføres på denne arbejdsbænk.
Guiden Library Model kan nu bruges til at oprette en ny forekomst af modellen.
Rodobjektet i denne editor svarer til ressourcen My.library. Under det findes et enkelt objekt ved navn Library, som blev valgt som modelobjekt i guiden.